On Tue, 1 May 2012 10:42:52 -0700 (PDT) Chris Stankevitz wrote:
CS> This email is a follow up of
http://trac.wxwidgets.org/ticket/12886
Hi Chris,
Thanks for following up.
CS> First let me say that the patch I created in ticket 12886 was not
CS> intended to be committed. It is simply what I am using to work around
CS> a problem (which could be of my own making). I tried to highlight
CS> this with the word "hack" in the patch filename. My rambling comments
CS> on the bug report (as I was learning) just served to make the bug
CS> report a big mess. I apologize for that.
No need to apologize and thanks for looking at this at all, I do
appreciate the amount of courage that diving into wxSocket code requires!
CS> For the rest of this email I will use these terms:
CS>
CS> GTK Events: GTK callbacks that the wxSocket code uses
Maybe we should call those "GTK callbacks" to avoid confusion with wx
events?
CS> Problem:
CS> A wxGTK application will crash if it attempts to use a wxSocket in a
CS> Worker Thread
The problem here is that wxSocket is, IMO/AFAIK, supposed to be used in
non-blocking mode from the main thread or in blocking mode (i.e. with
wxSOCKET_BLOCK flag) from a worker one. Apparently nobody, and definitely
not me, thought about using wxSOCKET_NOWAIT from a worker thread...
CS> Reason:
CS> wxSockets use GTK Events (which I do not understand).
GTK callbacks are used to integrate the sockets with the event loop.
They're necessary to allow using sockets asynchronously (i.e. in
non-blocking mode) in the main thread: instead of blocking on the socket
until it has something to read, or polling it, we just wait for something
to become available and are notified by this via the event loop. So this is
something that can only be done in the main thread.
CS> My use case:
CS> I use wxSockets in the following mode:
CS> 1. With wxSOCKET_NOWAIT
CS> 2. Without wxSocket Events (i.e. wxSocket::SetNofify = false)
The socket events are actually, I think, completely orthogonal to
everything else. I.e. they don't fundamentally modify the socket behaviour.
CS> When I want to write data, I call wxSocket::Write. If the data does
CS> not get written immediately, I will come back later and call Write
CS> again.
CS>
CS> When I want to read data, I call wxSocket::Read. If there is no data
CS> to read, I will try again later.
CS>
CS> Note I am not instigated to read by a wxSocket Event, I just do it on
CS> my own.
I see, thanks for the explanation. So this is actually a non-blocking-
but-polling mode which is something yet different from the 2 modes I had in
mind (fully asynchronous in the main thread or blocking in the worker).
CS> Bold proclamation:
CS> Although I do not understand what GTK Events do, when (1) and (2) are
CS> true, GTK Events are not needed. I "proved" this to myself with the
CS> patch in bug 12886.
Yes, I agree.
CS> Conclusion:
CS> 3. wxSocket uses wxGTK Events which makes wxSocket not thread safe.
CS> 4. GTK Events are not needed when (1) and (2)
CS> 5. For the special case of (1) and (2), GTK Events can be disabled,
CS> making wxSocket thread safe
CS>
CS> My patch in bug report 12886 implements (5).
I wonder if we shouldn't go further and just always avoid the use of GTK
callbacks in non-main thread? Can you (or anybody else brave enough to read
this thread) think of any case when they would be needed? This would be
simpler than trying to enable the events dynamically IMHO.
What do you think?
VZ