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

460
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
AC_FUNC_VPRINTF
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_CPLUSPLUS

View File

@ -1434,6 +1434,18 @@ This function is now obsolete, replaced by \helpref{Log functions}{logfunctions}
<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}
\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))
// Return a string with the current date/time
WXDLLEXPORT wxString wxNow(void);
WXDLLEXPORT wxString wxNow();
// Make a copy of this string using 'new'
WXDLLEXPORT char* copystring(const char *s);
// Generate a unique ID
WXDLLEXPORT long wxNewId(void);
WXDLLEXPORT long wxNewId();
#define NewId wxNewId
// Ensure subsequent IDs don't clash with this one
@ -63,7 +63,7 @@ WXDLLEXPORT void wxRegisterId(long id);
#define RegisterId wxRegisterId
// Return the current ID
WXDLLEXPORT long wxGetCurrentId(void);
WXDLLEXPORT long wxGetCurrentId();
// Useful buffer
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
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)
WXDLLEXPORT long wxGetFreeMemory(void);
WXDLLEXPORT long wxGetFreeMemory();
// Consume all events until no more left
WXDLLEXPORT void wxFlushEvents(void);
WXDLLEXPORT void wxFlushEvents();
/*
* 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))
// Yield to other apps/messages
WXDLLEXPORT bool wxYield(void);
WXDLLEXPORT bool wxYield();
// Format a message on the standard error (UNIX) or the debugging
// stream (Windows)
@ -184,20 +187,22 @@ WXDLLEXPORT_DATA(extern wxCursor*) wxHOURGLASS_CURSOR;
WXDLLEXPORT void wxBeginBusyCursor(wxCursor *cursor = wxHOURGLASS_CURSOR);
// Restore cursor to normal
WXDLLEXPORT void wxEndBusyCursor(void);
WXDLLEXPORT void wxEndBusyCursor();
// 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
class WXDLLEXPORT wxBusyCursor
{
public:
inline wxBusyCursor(wxCursor* cursor = wxHOURGLASS_CURSOR) { wxBeginBusyCursor(cursor); }
inline ~wxBusyCursor() { wxEndBusyCursor(); }
public:
wxBusyCursor(wxCursor* cursor = wxHOURGLASS_CURSOR)
{ wxBeginBusyCursor(cursor); }
~wxBusyCursor()
{ wxEndBusyCursor(); }
};
/* Error message functions used by wxWindows */
// Error message functions used by wxWindows
// Non-fatal error (continues)
WXDLLEXPORT_DATA(extern const char*) wxInternalErrorStr;

View File

@ -374,6 +374,18 @@
/* Define if you 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. */
#undef HAVE_GETLOADAVG

View File

@ -54,20 +54,20 @@ wxHashTable* wxClassInfo::sm_classTable = (wxHashTable*) NULL;
* wxWindows root object.
*/
wxObject::wxObject(void)
wxObject::wxObject()
{
m_refData = (wxObjectRefData *) NULL;
m_refData = (wxObjectRefData *) NULL;
#if wxUSE_SERIAL
m_serialObj = (wxObject_Serialize *)NULL;
m_serialObj = (wxObject_Serialize *)NULL;
#endif
}
wxObject::~wxObject(void)
wxObject::~wxObject()
{
UnRef();
UnRef();
#if wxUSE_SERIAL
if (m_serialObj)
delete m_serialObj;
if (m_serialObj)
delete m_serialObj;
#endif
}
@ -77,23 +77,23 @@ wxObject::~wxObject(void)
* Go from this class to superclass, taking into account
* two possible base classes.
*/
bool wxObject::IsKindOf(wxClassInfo *info) const
{
wxClassInfo *thisInfo = GetClassInfo();
if (thisInfo)
return thisInfo->IsKindOf(info);
else
return FALSE;
wxClassInfo *thisInfo = GetClassInfo();
if (thisInfo)
return thisInfo->IsKindOf(info);
else
return FALSE;
}
#if defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT
void wxObject::Dump(ostream& str)
{
if (GetClassInfo() && GetClassInfo()->GetClassName())
str << GetClassInfo()->GetClassName();
else
str << "unknown object class";
if (GetClassInfo() && GetClassInfo()->GetClassName())
str << GetClassInfo()->GetClassName();
else
str << "unknown object class";
}
#endif
@ -103,21 +103,21 @@ void wxObject::Dump(ostream& str)
#undef new
#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);
}
void wxObject::operator delete (void * buf)
{
wxDebugFree(buf);
wxDebugFree(buf);
}
// VC++ 6.0
#if defined(__VISUALC__) && (__VISUALC__ >= 1200)
void wxObject::operator delete(void* pData, char* /* fileName */, int /* lineNum */)
{
::operator delete(pData);
::operator delete(pData);
}
#endif
@ -125,12 +125,12 @@ void wxObject::operator delete(void* pData, char* /* fileName */, int /* lineNum
#if !defined(__VISUALC__) && wxUSE_ARRAY_MEMORY_OPERATORS
void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
{
return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
}
void wxObject::operator delete[] (void * buf)
{
wxDebugFree(buf, TRUE);
wxDebugFree(buf, TRUE);
}
#endif
@ -142,97 +142,97 @@ void wxObject::operator delete[] (void * buf)
wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn constr)
{
m_className = cName;
m_baseClassName1 = baseName1;
m_baseClassName2 = baseName2;
m_className = cName;
m_baseClassName1 = baseName1;
m_baseClassName2 = baseName2;
m_objectSize = sz;
m_objectConstructor = constr;
m_next = sm_first;
sm_first = this;
m_objectSize = sz;
m_objectConstructor = constr;
m_baseInfo1 = (wxClassInfo *) NULL;
m_baseInfo2 = (wxClassInfo *) NULL;
m_next = sm_first;
sm_first = this;
m_baseInfo1 = (wxClassInfo *) NULL;
m_baseInfo2 = (wxClassInfo *) NULL;
}
wxObject *wxClassInfo::CreateObject(void)
wxObject *wxClassInfo::CreateObject()
{
if (m_objectConstructor)
return (wxObject *)(*m_objectConstructor)();
else
return (wxObject *) NULL;
if (m_objectConstructor)
return (wxObject *)(*m_objectConstructor)();
else
return (wxObject *) NULL;
}
wxClassInfo *wxClassInfo::FindClass(char *c)
{
wxClassInfo *p = sm_first;
while (p)
{
if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
return p;
p = p->m_next;
}
return (wxClassInfo *) NULL;
wxClassInfo *p = sm_first;
while (p)
{
if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
return p;
p = p->m_next;
}
return (wxClassInfo *) NULL;
}
// Climb upwards through inheritance hierarchy.
// Dual inheritance is catered for.
bool wxClassInfo::IsKindOf(wxClassInfo *info) const
{
if (info == NULL)
return FALSE;
if (info == NULL)
return FALSE;
// For some reason, when making/using a DLL, static data has to be included
// 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.
// PROBABLY NO LONGER TRUE now I've done DLL creation right.
/*
// For some reason, when making/using a DLL, static data has to be included
// 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.
// PROBABLY NO LONGER TRUE now I've done DLL creation right.
/*
#if WXMAKINGDLL
if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
return TRUE;
if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
return TRUE;
#else
*/
if (this == info)
return TRUE;
*/
if (this == info)
return TRUE;
if (m_baseInfo1)
if (m_baseInfo1->IsKindOf(info))
return TRUE;
if (m_baseInfo1)
if (m_baseInfo1->IsKindOf(info))
return TRUE;
if (m_baseInfo2)
return m_baseInfo2->IsKindOf(info);
if (m_baseInfo2)
return m_baseInfo2->IsKindOf(info);
return FALSE;
return FALSE;
}
// 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);
// Index all class infos by their class name
wxClassInfo *info = sm_first;
while (info)
{
if (info->m_className)
sm_classTable->Put(info->m_className, (wxObject *)info);
info = info->m_next;
}
// Index all class infos by their class name
wxClassInfo *info = sm_first;
while (info)
{
if (info->m_className)
sm_classTable->Put(info->m_className, (wxObject *)info);
info = info->m_next;
}
// Set base pointers for each wxClassInfo
info = sm_first;
while (info)
{
if (info->GetBaseClassName1())
info->m_baseInfo1 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName1());
if (info->GetBaseClassName2())
info->m_baseInfo2 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName2());
info = info->m_next;
}
// Set base pointers for each wxClassInfo
info = sm_first;
while (info)
{
if (info->GetBaseClassName1())
info->m_baseInfo1 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName1());
if (info->GetBaseClassName2())
info->m_baseInfo2 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName2());
info = info->m_next;
}
}
void wxClassInfo::CleanUpClasses(void)
void wxClassInfo::CleanUpClasses()
{
delete wxClassInfo::sm_classTable;
wxClassInfo::sm_classTable = NULL;
@ -270,54 +270,54 @@ wxObject *wxCreateDynamicObject(const char *name)
wxObject* wxCreateStoredObject( wxInputStream &stream )
{
wxObjectInputStream obj_s(stream);
return obj_s.LoadObject();
wxObjectInputStream obj_s(stream);
return obj_s.LoadObject();
};
void wxObject::StoreObject( wxObjectOutputStream& stream )
{
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
if (!lib) {
wxLogError(_("Can't load wxSerial dynamic library."));
return;
}
if (!m_serialObj) {
m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
if (!m_serialObj) {
wxLogError(_("Can't find the serialization object '%s' "
"for the object '%s'."),
obj_name.c_str(),
GetClassInfo()->GetClassName());
return;
if (!lib) {
wxLogError(_("Can't load wxSerial dynamic library."));
return;
}
m_serialObj->SetObject(this);
}
if (!m_serialObj) {
m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
m_serialObj->StoreObject(stream);
if (!m_serialObj) {
wxLogError(_("Can't find the serialization object '%s' "
"for the object '%s'."),
obj_name.c_str(),
GetClassInfo()->GetClassName());
return;
}
m_serialObj->SetObject(this);
}
m_serialObj->StoreObject(stream);
}
void wxObject::LoadObject( wxObjectInputStream& stream )
{
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
if (!m_serialObj) {
m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
if (!m_serialObj) {
wxLogError(_("Can't find the serialization object '%s' "
"for the object '%s'."),
obj_name.c_str(),
GetClassInfo()->GetClassName());
return;
}
m_serialObj->SetObject(this);
}
m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
m_serialObj->LoadObject(stream);
if (!m_serialObj) {
wxLogError(_("Can't find the serialization object '%s' "
"for the object '%s'."),
obj_name.c_str(),
GetClassInfo()->GetClassName());
return;
}
m_serialObj->SetObject(this);
}
m_serialObj->LoadObject(stream);
}
#endif // wxUSE_SERIAL
@ -337,7 +337,7 @@ void wxObject::Ref(const wxObject& clone)
}
}
void wxObject::UnRef(void)
void wxObject::UnRef()
{
if (m_refData) {
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__
#pragma implementation "app.h"
#pragma implementation "app.h"
#endif
#include "wx/app.h"
@ -20,35 +20,24 @@
#include "wx/font.h"
#include "wx/settings.h"
#include "wx/dialog.h"
#if wxUSE_WX_RESOURCES
#include "wx/resource.h"
#include "wx/resource.h"
#endif
#include "wx/module.h"
#include "wx/image.h"
#if wxUSE_THREADS
#include "wx/thread.h"
#endif
#include "unistd.h"
// 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()
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include "glib.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#include "wx/gtk/win_gtk.h"
#include <unistd.h> // usleep() on solaris
//-----------------------------------------------------------------------------
// global data
//-----------------------------------------------------------------------------
@ -160,14 +149,17 @@ END_EVENT_TABLE()
gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{
if (wxTheApp) while (wxTheApp->ProcessIdle()) {}
#if wxUSE_THREADS
if (wxTheApp)
{
while (wxTheApp->ProcessIdle())
{
}
}
wxMutexGuiLeave();
#endif
usleep(10000);
#if wxUSE_THREADS
wxUsleep(10);
wxMutexGuiEnter();
#endif
return TRUE;
}

View File

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

View File

@ -7,11 +7,6 @@
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
//#ifdef __GNUG__
//#pragma implementation "utils.h"
//#endif
#include "wx/utils.h"
#include "wx/string.h"
@ -32,17 +27,30 @@
#include <netdb.h>
#include <signal.h>
#include <fcntl.h> // for O_WRONLY and friends
#include <time.h> // nanosleep() and/or usleep()
#include "glib.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#include "gtk/gtkfeatures.h"
#include "gdk/gdkx.h"
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gtk/gtkfeatures.h>
#include <gdk/gdkx.h>
#ifdef __SVR4__
#include <sys/systeminfo.h>
#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
// headers - please add your system here if it is the case for your OS.
// SunOS (and Solaris) and DG-UX are like this.
@ -78,6 +86,30 @@ void wxSleep(int 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)
{
return kill(pid, sig);

View File

@ -8,7 +8,7 @@
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "app.h"
#pragma implementation "app.h"
#endif
#include "wx/app.h"
@ -20,35 +20,24 @@
#include "wx/font.h"
#include "wx/settings.h"
#include "wx/dialog.h"
#if wxUSE_WX_RESOURCES
#include "wx/resource.h"
#include "wx/resource.h"
#endif
#include "wx/module.h"
#include "wx/image.h"
#if wxUSE_THREADS
#include "wx/thread.h"
#endif
#include "unistd.h"
// 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()
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include "glib.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#include "wx/gtk/win_gtk.h"
#include <unistd.h> // usleep() on solaris
//-----------------------------------------------------------------------------
// global data
//-----------------------------------------------------------------------------
@ -160,14 +149,17 @@ END_EVENT_TABLE()
gint wxapp_idle_callback( gpointer WXUNUSED(data) )
{
if (wxTheApp) while (wxTheApp->ProcessIdle()) {}
#if wxUSE_THREADS
if (wxTheApp)
{
while (wxTheApp->ProcessIdle())
{
}
}
wxMutexGuiLeave();
#endif
usleep(10000);
#if wxUSE_THREADS
wxUsleep(10);
wxMutexGuiEnter();
#endif
return TRUE;
}

View File

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

View File

@ -7,11 +7,6 @@
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
//#ifdef __GNUG__
//#pragma implementation "utils.h"
//#endif
#include "wx/utils.h"
#include "wx/string.h"
@ -32,17 +27,30 @@
#include <netdb.h>
#include <signal.h>
#include <fcntl.h> // for O_WRONLY and friends
#include <time.h> // nanosleep() and/or usleep()
#include "glib.h"
#include "gdk/gdk.h"
#include "gtk/gtk.h"
#include "gtk/gtkfeatures.h"
#include "gdk/gdkx.h"
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gtk/gtkfeatures.h>
#include <gdk/gdkx.h>
#ifdef __SVR4__
#include <sys/systeminfo.h>
#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
// headers - please add your system here if it is the case for your OS.
// SunOS (and Solaris) and DG-UX are like this.
@ -78,6 +86,30 @@ void wxSleep(int 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)
{
return kill(pid, sig);

View File

@ -6,7 +6,7 @@
// Created: 17/09/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
@ -70,19 +70,19 @@ bool wxApp::Initialize()
#else
wxBuffer = new char[BUFSIZ + 512];
#endif
wxClassInfo::InitializeClasses();
wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
wxTheColourDatabase->Initialize();
wxInitializeStockLists();
wxInitializeStockObjects();
#if wxUSE_WX_RESOURCES
wxInitializeResourceSystem();
#endif
// For PostScript printing
#if wxUSE_POSTSCRIPT
/* Done using wxModule now
@ -91,14 +91,14 @@ bool wxApp::Initialize()
wxThePrintPaperDatabase->CreateDatabase();
*/
#endif
wxBitmap::InitStandardHandlers();
wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
wxModule::RegisterModules();
if (!wxModule::InitializeModules()) return FALSE;
return TRUE;
}
@ -106,32 +106,32 @@ void wxApp::CleanUp()
{
delete wxWidgetHashTable;
wxWidgetHashTable = NULL;
wxModule::CleanUpModules();
#if wxUSE_WX_RESOURCES
wxCleanUpResourceSystem();
#endif
wxDeleteStockObjects() ;
// Destroy all GDI lists, etc.
delete wxTheBrushList;
wxTheBrushList = NULL;
delete wxThePenList;
wxThePenList = NULL;
delete wxTheFontList;
wxTheFontList = NULL;
delete wxTheBitmapList;
wxTheBitmapList = NULL;
delete wxTheColourDatabase;
wxTheColourDatabase = NULL;
#if wxUSE_POSTSCRIPT
/* Done using wxModule now
wxInitializePrintSetupData(FALSE);
@ -139,17 +139,17 @@ void wxApp::CleanUp()
wxThePrintPaperDatabase = NULL;
*/
#endif
wxBitmap::CleanUpHandlers();
delete[] wxBuffer;
wxBuffer = NULL;
wxClassInfo::CleanUpClasses();
delete wxTheApp;
wxTheApp = NULL;
#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
// At this point we want to check if there are any memory
// blocks that aren't part of the wxDebugContext itself,
@ -162,7 +162,7 @@ void wxApp::CleanUp()
wxDebugContext::PrintStatistics();
}
#endif
// do it as the very last thing because everything else can log messages
wxLog::DontCreateOnDemand();
// do it as the very last thing because everything else can log messages
@ -180,10 +180,10 @@ int wxEntry( int argc, char *argv[] )
// checked, but this is a reasonable compromise.
wxDebugContext::SetCheckpoint();
#endif
if (!wxApp::Initialize())
return FALSE;
if (!wxTheApp)
{
if (!wxApp::GetInitializerFunction())
@ -191,55 +191,55 @@ int wxEntry( int argc, char *argv[] )
printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
return 0;
};
wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
};
if (!wxTheApp)
{
printf( "wxWindows error: wxTheApp == NULL\n" );
return 0;
};
wxTheApp->SetClassName(wxFileNameFromPath(argv[0]));
wxTheApp->SetAppName(wxFileNameFromPath(argv[0]));
wxTheApp->argc = argc;
wxTheApp->argv = argv;
// GUI-specific initialization, such as creating an app context.
wxTheApp->OnInitGui();
// Here frames insert themselves automatically
// into wxTopLevelWindows by getting created
// in OnInit().
int retValue = 0;
if (wxTheApp->OnInit())
{
if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
}
// flush the logged messages if any
wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL && pLog->HasPendingMessages() )
pLog->Flush();
delete wxLog::SetActiveTarget(new wxLogStderr); // So dialog boxes aren't used
// for further messages
if (wxTheApp->GetTopWindow())
{
delete wxTheApp->GetTopWindow();
wxTheApp->SetTopWindow(NULL);
}
wxTheApp->DeletePendingObjects();
wxTheApp->OnExit();
wxApp::CleanUp();
return retValue;
};
@ -258,7 +258,7 @@ wxApp::wxApp()
m_printMode = wxPRINT_POSTSCRIPT;
m_exitOnFrameDelete = TRUE;
m_auto3D = TRUE;
m_mainColormap = (WXColormap) NULL;
m_appContext = (WXAppContext) NULL;
m_topLevelWidget = (WXWidget) NULL;
@ -277,42 +277,41 @@ bool wxApp::Initialized()
int wxApp::MainLoop()
{
m_keepGoing = TRUE;
/*
* Sit around forever waiting to process X-events. Property Change
* event are handled special, because they have to refer to
* the root window rather than to a widget. therefore we can't
* use an Xt-eventhandler.
*/
XSelectInput(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()),
XDefaultRootWindow(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())),
PropertyChangeMask);
XEvent event;
// Use this flag to allow breaking the loop via wxApp::ExitMainLoop()
while (m_keepGoing)
{
XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &event);
ProcessXEvent((WXEvent*) & event);
if (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) == 0)
{
if (!ProcessIdle())
{
// TODO: Robert, what's this for?
#if wxUSE_THREADS
{
// leave the main loop to give other threads a chance to
// perform their GUI work
wxMutexGuiLeave();
usleep(20);
wxUsleep(20);
wxMutexGuiEnter();
#endif
}
}
}
return 0;
}
@ -320,7 +319,7 @@ int wxApp::MainLoop()
void wxApp::ProcessXEvent(WXEvent* _event)
{
XEvent* event = (XEvent*) _event;
if ((event->type == KeyPress) && CheckForAccelerator(_event))
{
// Do nothing! We intercepted and processed the event as an accelerator.
@ -337,18 +336,18 @@ void wxApp::ProcessXEvent(WXEvent* _event)
* If resize event, don't resize until the last resize event for this
* window is recieved. Prevents flicker as windows are resized.
*/
Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
Window win = event->xany.window;
XEvent report;
// to avoid flicker
report = * event;
while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
// TODO: when implementing refresh optimization, we can use
// XtAddExposureToRegion to expand the window's paint region.
XtDispatchEvent(event);
}
else
@ -363,7 +362,7 @@ bool wxApp::ProcessIdle()
wxIdleEvent event;
event.SetEventObject(this);
ProcessEvent(event);
return event.MoreRequested();
}
@ -376,7 +375,7 @@ void wxApp::ExitMainLoop()
bool wxApp::Pending()
{
XFlush(XtDisplay( (Widget) wxTheApp->GetTopLevelWidget() ));
// Fix by Doug from STI, to prevent a stall if non-X event
// is found.
return ((XtAppPending( (XtAppContext) GetAppContext() ) & XtIMXEvent) != 0) ;
@ -386,7 +385,7 @@ bool wxApp::Pending()
void wxApp::Dispatch()
{
// XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
XEvent event;
XtAppNextEvent((XtAppContext) GetAppContext(), &event);
ProcessXEvent((WXEvent*) & event);
@ -403,27 +402,27 @@ void wxApp::HandlePropertyChange(WXEvent *event)
void wxApp::OnIdle(wxIdleEvent& event)
{
static bool inOnIdle = FALSE;
// Avoid recursion (via ProcessEvent default case)
if (inOnIdle)
return;
inOnIdle = TRUE;
// 'Garbage' collection of windows deleted with Close().
DeletePendingObjects();
// flush the logged messages if any
wxLog *pLog = wxLog::GetActiveTarget();
if ( pLog != NULL && pLog->HasPendingMessages() )
pLog->Flush();
// Send OnIdle events to all windows
bool needMore = SendIdleEvents();
if (needMore)
event.RequestMore(TRUE);
inOnIdle = FALSE;
}
@ -437,7 +436,7 @@ bool wxApp::SendIdleEvents()
wxWindow* win = (wxWindow*) node->Data();
if (SendIdleEvents(win))
needMore = TRUE;
node = node->Next();
}
return needMore;
@ -447,21 +446,21 @@ bool wxApp::SendIdleEvents()
bool wxApp::SendIdleEvents(wxWindow* win)
{
bool needMore = FALSE;
wxIdleEvent event;
event.SetEventObject(win);
win->ProcessEvent(event);
if (event.MoreRequested())
needMore = TRUE;
wxNode* node = win->GetChildren().First();
while (node)
{
wxWindow* win = (wxWindow*) node->Data();
if (SendIdleEvents(win))
needMore = TRUE;
node = node->Next();
}
return needMore ;
@ -473,12 +472,12 @@ void wxApp::DeletePendingObjects()
while (node)
{
wxObject *obj = (wxObject *)node->Data();
delete obj;
if (wxPendingDelete.Member(obj))
delete node;
// Deleting one object may have deleted other pending
// objects, so start from beginning of list again.
node = wxPendingDelete.First();
@ -517,20 +516,20 @@ bool wxApp::OnInitGui()
exit(-1);
}
m_initialDisplay = (WXDisplay*) dpy;
wxTheApp->m_topLevelWidget = (WXWidget) XtAppCreateShell((String)NULL, (const char*) wxTheApp->GetClassName(),
applicationShellWidgetClass,dpy,
NULL,0) ;
// Add general resize proc
XtActionsRec rec;
rec.string = "resize";
rec.proc = (XtActionProc)wxWidgetResizeProc;
XtAppAddActions((XtAppContext) wxTheApp->m_appContext, &rec, 1);
GetMainColormap(dpy);
m_maxRequestSize = XMaxRequestSize((Display*) dpy);
return TRUE;
}
@ -541,12 +540,12 @@ WXColormap wxApp::GetMainColormap(WXDisplay* display)
int defaultScreen = DefaultScreen((Display*) display);
Screen* screen = XScreenOfDisplay((Display*) display, defaultScreen);
Colormap c = DefaultColormapOfScreen(screen);
if (!m_mainColormap)
m_mainColormap = (WXColormap) c;
return (WXColormap) c;
}
@ -560,17 +559,17 @@ bool wxApp::CheckForAccelerator(WXEvent* event)
// TODO: should get display for the window, not the current display
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(), xEvent->xany.window);
wxWindow* win = NULL;
// Find the first wxWindow that corresponds to this event window
while (widget && !(win = wxGetWindowFromTable(widget)))
widget = XtParent(widget);
if (!widget || !win)
return FALSE;
wxKeyEvent keyEvent(wxEVT_CHAR);
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
// Now we have a wxKeyEvent and we have a wxWindow.
// Go up the hierarchy until we find a matching accelerator,
// or we get to the top.
@ -590,7 +589,7 @@ void wxExit()
int retValue = 0;
if (wxTheApp)
retValue = wxTheApp->OnExit();
wxApp::CleanUp();
/*
* Exit in some platform-specific way. Not recommended that the app calls this:

View File

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