wxUsleep() introduced (and documented) to try to work around usleep() bug in

MT programs under Solaris


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1852 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
1999-03-03 17:11:14 +00:00
parent ba6f401d45
commit afb7489128
14 changed files with 643 additions and 503 deletions

458
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -450,7 +450,10 @@ AC_SUBST(GTK_JOYSTICK)
dnl check for vprintf/vsprintf() which are GNU extensions dnl check for vprintf/vsprintf() which are GNU extensions
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
dnl check for vsnprintf() which is another GNU extension dnl check for vsnprintf() which is another GNU extension
AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF)) AC_CHECK_FUNCS(vsnprintf)
dnl check for usleep() and nanosleep() which is better in MT programs
AC_CHECK_FUNCS(nanosleep usleep)
AC_LANG_SAVE AC_LANG_SAVE
AC_LANG_CPLUSPLUS AC_LANG_CPLUSPLUS

View File

@@ -1434,6 +1434,18 @@ This function is now obsolete, replaced by \helpref{Log functions}{logfunctions}
<wx/memory.h> <wx/memory.h>
\membersection{::wxUsleep}\label{wxusleep}
\func{void}{wxUsleep}{\param{unsigned long}{ milliseconds}}
Sleeps for the specified number of milliseconds. Notice that usage of this
function is encouraged instead of calling usleep(3) directly because the
standard usleep() function is not MT safe.
\wxheading{Include files}
<wx/utils.h>
\membersection{::wxWriteResource}\label{wxwriteresource} \membersection{::wxWriteResource}\label{wxwriteresource}
\func{bool}{wxWriteResource}{\param{const wxString\& }{section}, \param{const wxString\& }{entry}, \func{bool}{wxWriteResource}{\param{const wxString\& }{section}, \param{const wxString\& }{entry},

View File

@@ -49,13 +49,13 @@ class WXDLLEXPORT wxFrame;
#define wxToLower(C) (((C) >= 'A' && (C) <= 'Z')? (C) - 'A' + 'a': (C)) #define wxToLower(C) (((C) >= 'A' && (C) <= 'Z')? (C) - 'A' + 'a': (C))
// Return a string with the current date/time // Return a string with the current date/time
WXDLLEXPORT wxString wxNow(void); WXDLLEXPORT wxString wxNow();
// Make a copy of this string using 'new' // Make a copy of this string using 'new'
WXDLLEXPORT char* copystring(const char *s); WXDLLEXPORT char* copystring(const char *s);
// Generate a unique ID // Generate a unique ID
WXDLLEXPORT long wxNewId(void); WXDLLEXPORT long wxNewId();
#define NewId wxNewId #define NewId wxNewId
// Ensure subsequent IDs don't clash with this one // Ensure subsequent IDs don't clash with this one
@@ -63,7 +63,7 @@ WXDLLEXPORT void wxRegisterId(long id);
#define RegisterId wxRegisterId #define RegisterId wxRegisterId
// Return the current ID // Return the current ID
WXDLLEXPORT long wxGetCurrentId(void); WXDLLEXPORT long wxGetCurrentId();
// Useful buffer // Useful buffer
WXDLLEXPORT_DATA(extern char*) wxBuffer; WXDLLEXPORT_DATA(extern char*) wxBuffer;
@@ -111,11 +111,14 @@ WXDLLEXPORT bool wxShell(const wxString& command = wxEmptyString);
// Sleep for nSecs seconds under UNIX, do nothing under Windows // Sleep for nSecs seconds under UNIX, do nothing under Windows
WXDLLEXPORT void wxSleep(int nSecs); WXDLLEXPORT void wxSleep(int nSecs);
// Sleep for a given amount of milliseconds
WXDLLEXPORT void wxUsleep(unsigned long milliseconds);
// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
WXDLLEXPORT long wxGetFreeMemory(void); WXDLLEXPORT long wxGetFreeMemory();
// Consume all events until no more left // Consume all events until no more left
WXDLLEXPORT void wxFlushEvents(void); WXDLLEXPORT void wxFlushEvents();
/* /*
* Network and username functions. * Network and username functions.
@@ -166,7 +169,7 @@ WXDLLEXPORT int wxFindMenuItemId(wxFrame *frame, const wxString& menuString, con
#define wxMin(a,b) (((a) < (b)) ? (a) : (b)) #define wxMin(a,b) (((a) < (b)) ? (a) : (b))
// Yield to other apps/messages // Yield to other apps/messages
WXDLLEXPORT bool wxYield(void); WXDLLEXPORT bool wxYield();
// Format a message on the standard error (UNIX) or the debugging // Format a message on the standard error (UNIX) or the debugging
// stream (Windows) // stream (Windows)
@@ -184,20 +187,22 @@ WXDLLEXPORT_DATA(extern wxCursor*) wxHOURGLASS_CURSOR;
WXDLLEXPORT void wxBeginBusyCursor(wxCursor *cursor = wxHOURGLASS_CURSOR); WXDLLEXPORT void wxBeginBusyCursor(wxCursor *cursor = wxHOURGLASS_CURSOR);
// Restore cursor to normal // Restore cursor to normal
WXDLLEXPORT void wxEndBusyCursor(void); WXDLLEXPORT void wxEndBusyCursor();
// TRUE if we're between the above two calls // TRUE if we're between the above two calls
WXDLLEXPORT bool wxIsBusy(void); WXDLLEXPORT bool wxIsBusy();
// Convenience class so we can just create a wxBusyCursor object on the stack // Convenience class so we can just create a wxBusyCursor object on the stack
class WXDLLEXPORT wxBusyCursor class WXDLLEXPORT wxBusyCursor
{ {
public: public:
inline wxBusyCursor(wxCursor* cursor = wxHOURGLASS_CURSOR) { wxBeginBusyCursor(cursor); } wxBusyCursor(wxCursor* cursor = wxHOURGLASS_CURSOR)
inline ~wxBusyCursor() { wxEndBusyCursor(); } { wxBeginBusyCursor(cursor); }
~wxBusyCursor()
{ wxEndBusyCursor(); }
}; };
/* Error message functions used by wxWindows */ // Error message functions used by wxWindows
// Non-fatal error (continues) // Non-fatal error (continues)
WXDLLEXPORT_DATA(extern const char*) wxInternalErrorStr; WXDLLEXPORT_DATA(extern const char*) wxInternalErrorStr;

View File

@@ -374,6 +374,18 @@
/* Define if you have vsnprintf() */ /* Define if you have vsnprintf() */
#undef HAVE_VSNPRINTF #undef HAVE_VSNPRINTF
/* Define if you have usleep() */
#undef HAVE_USLEEP
/* Define if you have nanosleep() */
#undef HAVE_NANOSLEEP
/* Define if you have usleep() */
#undef HAVE_USLEEP
/* Define if you have nanosleep() */
#undef HAVE_NANOSLEEP
/* Define if your system has its own `getloadavg' function. */ /* Define if your system has its own `getloadavg' function. */
#undef HAVE_GETLOADAVG #undef HAVE_GETLOADAVG

View File

@@ -54,7 +54,7 @@ wxHashTable* wxClassInfo::sm_classTable = (wxHashTable*) NULL;
* wxWindows root object. * wxWindows root object.
*/ */
wxObject::wxObject(void) wxObject::wxObject()
{ {
m_refData = (wxObjectRefData *) NULL; m_refData = (wxObjectRefData *) NULL;
#if wxUSE_SERIAL #if wxUSE_SERIAL
@@ -62,7 +62,7 @@ wxObject::wxObject(void)
#endif #endif
} }
wxObject::~wxObject(void) wxObject::~wxObject()
{ {
UnRef(); UnRef();
#if wxUSE_SERIAL #if wxUSE_SERIAL
@@ -103,7 +103,7 @@ void wxObject::Dump(ostream& str)
#undef new #undef new
#endif #endif
void * wxObject::operator new (size_t size, char * fileName, int lineNum) void *wxObject::operator new (size_t size, char * fileName, int lineNum)
{ {
return wxDebugAlloc(size, fileName, lineNum, TRUE); return wxDebugAlloc(size, fileName, lineNum, TRUE);
} }
@@ -156,7 +156,7 @@ wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz,
m_baseInfo2 = (wxClassInfo *) NULL; m_baseInfo2 = (wxClassInfo *) NULL;
} }
wxObject *wxClassInfo::CreateObject(void) wxObject *wxClassInfo::CreateObject()
{ {
if (m_objectConstructor) if (m_objectConstructor)
return (wxObject *)(*m_objectConstructor)(); return (wxObject *)(*m_objectConstructor)();
@@ -187,12 +187,12 @@ bool wxClassInfo::IsKindOf(wxClassInfo *info) const
// in both the DLL and the application. This can lead to duplicate // in both the DLL and the application. This can lead to duplicate
// wxClassInfo objects, so we have to test the name instead of the pointers. // wxClassInfo objects, so we have to test the name instead of the pointers.
// PROBABLY NO LONGER TRUE now I've done DLL creation right. // PROBABLY NO LONGER TRUE now I've done DLL creation right.
/* /*
#if WXMAKINGDLL #if WXMAKINGDLL
if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0)) if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
return TRUE; return TRUE;
#else #else
*/ */
if (this == info) if (this == info)
return TRUE; return TRUE;
@@ -207,7 +207,7 @@ bool wxClassInfo::IsKindOf(wxClassInfo *info) const
} }
// Set pointers to base class(es) to speed up IsKindOf // Set pointers to base class(es) to speed up IsKindOf
void wxClassInfo::InitializeClasses(void) void wxClassInfo::InitializeClasses()
{ {
wxClassInfo::sm_classTable = new wxHashTable(wxKEY_STRING); wxClassInfo::sm_classTable = new wxHashTable(wxKEY_STRING);
@@ -232,7 +232,7 @@ void wxClassInfo::InitializeClasses(void)
} }
} }
void wxClassInfo::CleanUpClasses(void) void wxClassInfo::CleanUpClasses()
{ {
delete wxClassInfo::sm_classTable; delete wxClassInfo::sm_classTable;
wxClassInfo::sm_classTable = NULL; wxClassInfo::sm_classTable = NULL;
@@ -337,7 +337,7 @@ void wxObject::Ref(const wxObject& clone)
} }
} }
void wxObject::UnRef(void) void wxObject::UnRef()
{ {
if (m_refData) { if (m_refData) {
assert(m_refData->m_count > 0); assert(m_refData->m_count > 0);
@@ -356,7 +356,7 @@ wxObjectRefData::wxObjectRefData(void) : m_count(1)
{ {
} }
wxObjectRefData::~wxObjectRefData(void) wxObjectRefData::~wxObjectRefData()
{ {
} }

View File

@@ -8,7 +8,7 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "app.h" #pragma implementation "app.h"
#endif #endif
#include "wx/app.h" #include "wx/app.h"
@@ -20,35 +20,24 @@
#include "wx/font.h" #include "wx/font.h"
#include "wx/settings.h" #include "wx/settings.h"
#include "wx/dialog.h" #include "wx/dialog.h"
#if wxUSE_WX_RESOURCES #if wxUSE_WX_RESOURCES
#include "wx/resource.h" #include "wx/resource.h"
#endif #endif
#include "wx/module.h" #include "wx/module.h"
#include "wx/image.h" #include "wx/image.h"
#if wxUSE_THREADS
#include "wx/thread.h" #include "wx/thread.h"
#endif
#include "unistd.h" #include "unistd.h"
// many versions of Unices have this function, but it is not defined in system #include <glib.h>
// headers - please add your system here if it is the case for your OS. #include <gdk/gdk.h>
// SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this. #include <gtk/gtk.h>
#if (defined(__SUN__) && !defined(__SunOs_5_6) && \
!defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
defined(__osf__)
extern "C"
{
void usleep(unsigned long usec);
};
#endif // Unices without usleep()
#include "glib.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#include "wx/gtk/win_gtk.h" #include "wx/gtk/win_gtk.h"
#include <unistd.h> // usleep() on solaris
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// global data // global data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -160,14 +149,17 @@ END_EVENT_TABLE()
gint wxapp_idle_callback( gpointer WXUNUSED(data) ) gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{ {
if (wxTheApp) while (wxTheApp->ProcessIdle()) {} if (wxTheApp)
#if wxUSE_THREADS {
while (wxTheApp->ProcessIdle())
{
}
}
wxMutexGuiLeave(); wxMutexGuiLeave();
#endif wxUsleep(10);
usleep(10000);
#if wxUSE_THREADS
wxMutexGuiEnter(); wxMutexGuiEnter();
#endif
return TRUE; return TRUE;
} }

View File

@@ -410,9 +410,7 @@ void wxThread::Yield()
void wxThread::Sleep(unsigned long milliseconds) void wxThread::Sleep(unsigned long milliseconds)
{ {
// FIXME how to test for nanosleep() availability? wxUsleep(milliseconds);
usleep(milliseconds * 1000); // usleep(3) wants microseconds
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -7,11 +7,6 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
//#ifdef __GNUG__
//#pragma implementation "utils.h"
//#endif
#include "wx/utils.h" #include "wx/utils.h"
#include "wx/string.h" #include "wx/string.h"
@@ -32,17 +27,30 @@
#include <netdb.h> #include <netdb.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h> // for O_WRONLY and friends #include <fcntl.h> // for O_WRONLY and friends
#include <time.h> // nanosleep() and/or usleep()
#include "glib.h" #include <glib.h>
#include "gdk/gdk.h" #include <gdk/gdk.h>
#include "gtk/gtk.h" #include <gtk/gtk.h>
#include "gtk/gtkfeatures.h" #include <gtk/gtkfeatures.h>
#include "gdk/gdkx.h" #include <gdk/gdkx.h>
#ifdef __SVR4__ #ifdef __SVR4__
#include <sys/systeminfo.h> #include <sys/systeminfo.h>
#endif #endif
// many versions of Unices have this function, but it is not defined in system
// headers - please add your system here if it is the case for your OS.
// SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this.
#if (defined(__SUN__) && !defined(__SunOs_5_6) && \
!defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
defined(__osf__)
extern "C"
{
void usleep(unsigned long usec);
};
#endif // Unices without usleep()
// many versions of Unices have this function, but it is not defined in system // many versions of Unices have this function, but it is not defined in system
// headers - please add your system here if it is the case for your OS. // headers - please add your system here if it is the case for your OS.
// SunOS (and Solaris) and DG-UX are like this. // SunOS (and Solaris) and DG-UX are like this.
@@ -78,6 +86,30 @@ void wxSleep(int nSecs)
sleep(nSecs); sleep(nSecs);
} }
void wxUsleep(unsigned long milliseconds)
{
#if defined(HAVE_NANOSLEEP)
timespec tmReq;
tmReq.tv_sec = milliseconds / 1000;
tmReq.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
// we're not interested in remaining time nor in return value
(void)nanosleep(&tmReq, (timespec *)NULL);
#elif defined(HAVE_USLEEP)
// uncomment this if you feel brave or if you are sure that your version
// of Solaris has a safe usleep() function but please notice that usleep()
// is known to lead to crashes in MT programs in Solaris 2.[67] and is not
// documented as MT-Safe
#if defined(__SUN__) && defined(wxUSE_THREADS)
#error "usleep() cannot be used in MT programs under Solaris."
#endif // Sun
usleep(milliseconds * 1000); // usleep(3) wants microseconds
#else // !sleep function
#error "usleep() or nanosleep() function required for wxUsleep"
#endif // sleep function
}
int wxKill(long pid, int sig) int wxKill(long pid, int sig)
{ {
return kill(pid, sig); return kill(pid, sig);

View File

@@ -8,7 +8,7 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "app.h" #pragma implementation "app.h"
#endif #endif
#include "wx/app.h" #include "wx/app.h"
@@ -20,35 +20,24 @@
#include "wx/font.h" #include "wx/font.h"
#include "wx/settings.h" #include "wx/settings.h"
#include "wx/dialog.h" #include "wx/dialog.h"
#if wxUSE_WX_RESOURCES #if wxUSE_WX_RESOURCES
#include "wx/resource.h" #include "wx/resource.h"
#endif #endif
#include "wx/module.h" #include "wx/module.h"
#include "wx/image.h" #include "wx/image.h"
#if wxUSE_THREADS
#include "wx/thread.h" #include "wx/thread.h"
#endif
#include "unistd.h" #include "unistd.h"
// many versions of Unices have this function, but it is not defined in system #include <glib.h>
// headers - please add your system here if it is the case for your OS. #include <gdk/gdk.h>
// SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this. #include <gtk/gtk.h>
#if (defined(__SUN__) && !defined(__SunOs_5_6) && \
!defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
defined(__osf__)
extern "C"
{
void usleep(unsigned long usec);
};
#endif // Unices without usleep()
#include "glib.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#include "wx/gtk/win_gtk.h" #include "wx/gtk/win_gtk.h"
#include <unistd.h> // usleep() on solaris
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// global data // global data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -160,14 +149,17 @@ END_EVENT_TABLE()
gint wxapp_idle_callback( gpointer WXUNUSED(data) ) gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{ {
if (wxTheApp) while (wxTheApp->ProcessIdle()) {} if (wxTheApp)
#if wxUSE_THREADS {
while (wxTheApp->ProcessIdle())
{
}
}
wxMutexGuiLeave(); wxMutexGuiLeave();
#endif wxUsleep(10);
usleep(10000);
#if wxUSE_THREADS
wxMutexGuiEnter(); wxMutexGuiEnter();
#endif
return TRUE; return TRUE;
} }

View File

@@ -410,9 +410,7 @@ void wxThread::Yield()
void wxThread::Sleep(unsigned long milliseconds) void wxThread::Sleep(unsigned long milliseconds)
{ {
// FIXME how to test for nanosleep() availability? wxUsleep(milliseconds);
usleep(milliseconds * 1000); // usleep(3) wants microseconds
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -7,11 +7,6 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
//#ifdef __GNUG__
//#pragma implementation "utils.h"
//#endif
#include "wx/utils.h" #include "wx/utils.h"
#include "wx/string.h" #include "wx/string.h"
@@ -32,17 +27,30 @@
#include <netdb.h> #include <netdb.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h> // for O_WRONLY and friends #include <fcntl.h> // for O_WRONLY and friends
#include <time.h> // nanosleep() and/or usleep()
#include "glib.h" #include <glib.h>
#include "gdk/gdk.h" #include <gdk/gdk.h>
#include "gtk/gtk.h" #include <gtk/gtk.h>
#include "gtk/gtkfeatures.h" #include <gtk/gtkfeatures.h>
#include "gdk/gdkx.h" #include <gdk/gdkx.h>
#ifdef __SVR4__ #ifdef __SVR4__
#include <sys/systeminfo.h> #include <sys/systeminfo.h>
#endif #endif
// many versions of Unices have this function, but it is not defined in system
// headers - please add your system here if it is the case for your OS.
// SunOS < 5.6 (i.e. Solaris < 2.6) and DG-UX are like this.
#if (defined(__SUN__) && !defined(__SunOs_5_6) && \
!defined(__SunOs_5_7) && !defined(__SUNPRO_CC)) || \
defined(__osf__)
extern "C"
{
void usleep(unsigned long usec);
};
#endif // Unices without usleep()
// many versions of Unices have this function, but it is not defined in system // many versions of Unices have this function, but it is not defined in system
// headers - please add your system here if it is the case for your OS. // headers - please add your system here if it is the case for your OS.
// SunOS (and Solaris) and DG-UX are like this. // SunOS (and Solaris) and DG-UX are like this.
@@ -78,6 +86,30 @@ void wxSleep(int nSecs)
sleep(nSecs); sleep(nSecs);
} }
void wxUsleep(unsigned long milliseconds)
{
#if defined(HAVE_NANOSLEEP)
timespec tmReq;
tmReq.tv_sec = milliseconds / 1000;
tmReq.tv_nsec = (milliseconds % 1000) * 1000 * 1000;
// we're not interested in remaining time nor in return value
(void)nanosleep(&tmReq, (timespec *)NULL);
#elif defined(HAVE_USLEEP)
// uncomment this if you feel brave or if you are sure that your version
// of Solaris has a safe usleep() function but please notice that usleep()
// is known to lead to crashes in MT programs in Solaris 2.[67] and is not
// documented as MT-Safe
#if defined(__SUN__) && defined(wxUSE_THREADS)
#error "usleep() cannot be used in MT programs under Solaris."
#endif // Sun
usleep(milliseconds * 1000); // usleep(3) wants microseconds
#else // !sleep function
#error "usleep() or nanosleep() function required for wxUsleep"
#endif // sleep function
}
int wxKill(long pid, int sig) int wxKill(long pid, int sig)
{ {
return kill(pid, sig); return kill(pid, sig);

View File

@@ -302,12 +302,11 @@ int wxApp::MainLoop()
{ {
if (!ProcessIdle()) if (!ProcessIdle())
{ {
// TODO: Robert, what's this for? // leave the main loop to give other threads a chance to
#if wxUSE_THREADS // perform their GUI work
wxMutexGuiLeave(); wxMutexGuiLeave();
usleep(20); wxUsleep(20);
wxMutexGuiEnter(); wxMutexGuiEnter();
#endif
} }
} }

View File

@@ -299,6 +299,11 @@ class wxSleepTimer: public wxTimer
static wxTimer *wxTheSleepTimer = NULL; static wxTimer *wxTheSleepTimer = NULL;
void wxUsleep(unsigned long milliseconds)
{
::Sleep(milliseconds);
}
void wxSleep(int nSecs) void wxSleep(int nSecs)
{ {
#if 0 // WIN32 hangs app #if 0 // WIN32 hangs app