From: Kip Warner on
Greetings,

I have a server that has a main GUI thread and a server listen thread.
When a client connects, a new thread is spawned to take care of
communication with that client. I do not use events at all for the
secondary threads and use only non-blocking sockets.

I notice that after a few hours of the server running, the main thread
locks up during the idle message handler where it looks for an old
client socket that was scheduled to be deleted, but it cannot find. It
loops forever in wxListBase::DeleteObject because it can never find the
socket node to delete.

When I am done with the socket in each client socket thread, I call
ClientSocket->Destroy() in the thread deconstructor. The thread exits
normally, but a while later, the main thread gets hung up as described.
Here is the main thread's stack trace...
wxwidgets:

#0 wxListBase::DeleteObject (this=0x2b3878f8e060,
object=0x2aaaad6d83e0) at ../src/common/list.cpp:417
#1 0x00002b38782ccbf5 in wxObjectList::DeleteObject
(this=0x2b3878f8e060, object=0x2aaaad6d83e0)
at ../include/wx/list.h:1178
#2 0x00002b3878b2f164 in wxGUIAppTraitsBase::RemoveFromPendingDelete
(this=0x6ded70, object=0x2aaaad6d83e0) at ../src/common/appcmn.cpp:638
#3 0x00002b38791cf20b in ~wxSocketBase (this=0x2aaaad6d83e0)
at ../src/common/socket.cpp:230
#4 0x00002b3878b2f7e3 in wxAppBase::DeletePendingObjects
(this=0x6a5040) at ../src/common/appcmn.cpp:419
#5 0x00002b3878b2f84b in wxAppBase::OnIdle (this=0x6a5040)
at ../src/common/appcmn.cpp:491
#6 0x00002b387947ec41 in wxAppConsole::HandleEvent (this=0x6a5040,
handler=0x6a5040, func=(void ( class wxEvtHandler::*)(class wxEvent &,))
253124355, event=(a)0x7fff33695c00) at ../src/common/appbase.cpp:320
#7 0x00002b3879531b12 in wxEvtHandler::ProcessEventIfMatches
(entry=(a)0x2b3878f8a1e0, handler=0x6a5040, event=(a)0x7fff33695c00)
at ../src/common/event.cpp:1204
#8 0x00002b3879533a07 in wxEventHashTable::HandleEvent
(this=0x2b3878f8a1a0, event=(a)0x7fff33695c00, self=0x6a5040)
at ../src/common/event.cpp:877
#9 0x00002b3879533b52 in wxEvtHandler::ProcessEvent (this=0x6a5040,
event=(a)0x7fff33695c00) at ../src/common/event.cpp:1266
#10 0x00002b3878b2f64f in wxAppBase::ProcessIdle (this=0x6a5040)
at ../src/common/appcmn.cpp:442
#11 0x00002b3878a6ab0a in wxapp_idle_callback ()
at ../src/gtk/app.cpp:207
#12 0x00002b387c8fcfd3 in g_main_context_dispatch ()
from /./usr/lib/libglib-2.0.so.0
#13 0x00002b387c9002dd in ?? () from /./usr/lib/libglib-2.0.so.0
#14 0x00002b387c9005ea in g_main_loop_run ()
from /./usr/lib/libglib-2.0.so.0
#15 0x00002b387cefc883 in gtk_main ()
from /./usr/lib/libgtk-x11-2.0.so.0
#16 0x00002b3878a8928f in wxEventLoop::Run (this=0x97aa90)
at ../src/gtk/evtloop.cpp:76
#17 0x00002b3878b2f1f4 in wxAppBase::MainLoop (this=0x6a5040)
at ../src/common/appcmn.cpp:308
#18 0x00002b3878b2ef61 in wxAppBase::OnRun (this=0x6a5040)
at ../src/common/appcmn.cpp:363
#19 0x00002b38794c36c1 in wxEntry (argc=(a)0x2b38797eb410, argv=0x6929c0)
at ../src/common/init.cpp:449
#20 0x00002b38794c378e in wxEntry (argc=(a)0x7fff33695fcc,
argv=0x7fff336960b8) at ../src/common/init.cpp:461
#21 0x00000000004309fc in main (argc=2, argv=0x7fff336960b8) at
src/server/MyApp.cpp:25

I call wxSocketBase::Initialize() from the main thread and have tried
calling Destroy() in the socket thread on the socket with and without
doing so conditionally on the return of IsConnected(). Same deal either
way.

Any help is appreciated.

--
Public Key:
gpg --keyserver pgp.mit.edu --search-keys kip(a)thevertigo.com

Kip Warner
Software Engineer
http://www.thevertigo.com
From: Lukasz Michalski on
On Thursday 20 December 2007, Kip Warner wrote:
> Greetings,
>
> When I am done with the socket in each client socket thread, I call
> ClientSocket->Destroy() in the thread deconstructor. The thread exits

Your problem is caused by ScheduleForDestroy() call from child thread which
modifies global list that is not thread safe.

I would rather call ClientSocket->Close() and delete pointer to socket in
thread that owns it. If you don't use events then there is no need for
Destroy(). Destroy() can be used safely only in main thread.

Regards,
--
Lukasz Michalski
pgp key: http://www.zork.pl/lm.asc
From: Kip Warner on
On Thu, 20 Dec 2007 16:33:01 +0100, Lukasz Michalski wrote:

> On Thursday 20 December 2007, Kip Warner wrote:
>> Greetings,
>>
>> When I am done with the socket in each client socket thread, I call
>> ClientSocket->Destroy() in the thread deconstructor. The thread exits
>
> Your problem is caused by ScheduleForDestroy() call from child thread
> which modifies global list that is not thread safe.
>
> I would rather call ClientSocket->Close() and delete pointer to socket
> in thread that owns it. If you don't use events then there is no need
> for Destroy(). Destroy() can be used safely only in main thread.
>
> Regards,

Thank you very much Lukasz. I will try that. Are you sure it is ok to
delete the socket object manually after calling close? The documentation
always says not to manually invoke the deconstructor like that and to
just use Destroy(). Also, your method isn't mentioned in the docs. Not
saying it isn't valid, in fact, it's the only method that makes sense
right now. I am just curious as to why something so critical as that
isn't in there since I am sure I am not the only one to not use sockets
through events and in a secondary thread?

Kip
From: Lukasz Michalski on
Kip Warner pisze:

> Thank you very much Lukasz. I will try that. Are you sure it is ok to
> delete the socket object manually after calling close? The documentation

Yes, I am sure.

> always says not to manually invoke the deconstructor like that and to
> just use Destroy(). Also, your method isn't mentioned in the docs. Not
> saying it isn't valid, in fact, it's the only method that makes sense
> right now. I am just curious as to why something so critical as that
> isn't in there since I am sure I am not the only one to not use sockets
> through events and in a secondary thread?

wxSockets have many mysteries hidden inside. Work is being done to
clarify most of them.

Regards,
--
Lukasz Michalski
pgp key: http://www.zork.pl/lm.asc

From: Kip Warner on
On Thu, 20 Dec 2007 22:10:24 +0100, Lukasz Michalski wrote:

> wxSockets have many mysteries hidden inside. Work is being done to
> clarify most of them.
>
> Regards,

Thank you Lukasz, I think that fixed the problem. =)

Kip