Synchronize access to wxSelectDispatcher from different threads

We reuse the same global dispatcher object (allocated in
wxFDIODispatcher::Get()) for the sockets created in different threads, so it's
perfectly possible for its methods to be called concurrently and this happens
even in our own socket streams unit tests.

Protect against concurrent modification of the select sets and m_maxFD. This
fixes sporadic Travis build failures such as the one at
https://travis-ci.org/wxWidgets/wxWidgets/jobs/110757281 for example and
probably even worse bugs too.
This commit is contained in:
Vadim Zeitlin 2016-02-21 18:47:46 +01:00
parent 513fca5d4c
commit e5c93ad674
2 changed files with 11 additions and 0 deletions

View File

@ -21,6 +21,7 @@
#include <sys/types.h>
#include "wx/thread.h"
#include "wx/private/fdiodispatcher.h"
// helper class storing all the select() fd sets
@ -108,6 +109,10 @@ private:
int DoSelect(wxSelectSets& sets, int timeout) const;
#if wxUSE_THREADS
wxCriticalSection m_cs;
#endif // wxUSE_THREADS
// the select sets containing all the registered fds
wxSelectSets m_sets;

View File

@ -133,6 +133,8 @@ bool wxSelectSets::Handle(int fd, wxFDIOHandler& handler) const
bool wxSelectDispatcher::RegisterFD(int fd, wxFDIOHandler *handler, int flags)
{
wxCRIT_SECT_LOCKER(lock, m_cs);
if ( !wxMappedFDIODispatcher::RegisterFD(fd, handler, flags) )
return false;
@ -149,6 +151,8 @@ bool wxSelectDispatcher::RegisterFD(int fd, wxFDIOHandler *handler, int flags)
bool wxSelectDispatcher::ModifyFD(int fd, wxFDIOHandler *handler, int flags)
{
wxCRIT_SECT_LOCKER(lock, m_cs);
if ( !wxMappedFDIODispatcher::ModifyFD(fd, handler, flags) )
return false;
@ -161,6 +165,8 @@ bool wxSelectDispatcher::ModifyFD(int fd, wxFDIOHandler *handler, int flags)
bool wxSelectDispatcher::UnregisterFD(int fd)
{
wxCRIT_SECT_LOCKER(lock, m_cs);
m_sets.ClearFD(fd);
if ( !wxMappedFDIODispatcher::UnregisterFD(fd) )