Merge branch 'blocking-sockets-fixes'

Closes #17937.
This commit is contained in:
Vadim Zeitlin
2017-08-21 13:22:53 +02:00
7 changed files with 65 additions and 14 deletions

View File

@@ -51,9 +51,25 @@ private:
virtual void UnblockAndRegisterWithEventLoop() wxOVERRIDE
{
// no need to make the socket non-blocking, Install_Callback() will do
// it
wxSocketManager::Get()->Install_Callback(this);
if ( GetSocketFlags() & wxSOCKET_BLOCK )
{
// Counter-intuitively, we make the socket non-blocking even in
// this case as it is necessary e.g. for Read() to return
// immediately if there is no data available. However we must not
// install a callback for it as blocking sockets don't use any
// events and generating them would actually be harmful (and not
// just useless) as they would be dispatched by the main thread
// while this blocking socket can be used from a worker one, so it
// would result in data races and other unpleasantness.
unsigned long trueArg = 1;
ioctlsocket(m_fd, FIONBIO, &trueArg);
}
else
{
// No need to make the socket non-blocking, Install_Callback() will
// do it as a side effect of calling WSAAsyncSelect().
wxSocketManager::Get()->Install_Callback(this);
}
}
int m_msgnumber;

View File

@@ -225,6 +225,16 @@ public:
bool IsNoWait() const { return ((m_flags & wxSOCKET_NOWAIT) != 0); }
wxSocketType GetType() const { return m_type; }
// Helper returning wxSOCKET_NONE if non-blocking sockets can be used, i.e.
// the socket is being created in the main thread and the event loop is
// running, or wxSOCKET_BLOCK otherwise.
//
// This is an internal function used only by wxWidgets itself, user code
// should decide if it wants blocking sockets or not and use the
// appropriate style instead of using it (but wxWidgets has to do it like
// this for compatibility with the original network classes behaviour).
static int GetBlockingFlagIfNeeded();
private:
friend class wxSocketClient;
friend class wxSocketServer;