diff --git a/ext/fox16_c/FXRbApp.cpp b/ext/fox16_c/FXRbApp.cpp index 11d8bb5ae0027341807f358cc08e12bf2513d2ec..b70c5db1808d9517bd341dea375d8fd9124f223c 100644 --- a/ext/fox16_c/FXRbApp.cpp +++ b/ext/fox16_c/FXRbApp.cpp @@ -36,19 +36,25 @@ extern "C" { #include <sys/time.h> /* For struct timeval */ #endif +#include <fcntl.h> + // Message map FXDEFMAP(FXRbApp) FXRbAppMap[]={ +#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) + FXMAPFUNC(SEL_IO_READ,FXRbApp::ID_CHORE_THREADS,FXRbApp::onChoreThreads), +#else FXMAPFUNC(SEL_CHORE,FXRbApp::ID_CHORE_THREADS,FXRbApp::onChoreThreads), +#endif }; // Class implementation FXRbIMPLEMENT(FXRbApp,FXApp,FXRbAppMap,ARRAYNUMBER(FXRbAppMap)) +int FXRbApp::interrupt_fds[2] = {-1, -1}; + // Constructor -FXRbApp::FXRbApp(const FXchar* appname,const FXchar* vendor) : FXApp(appname,vendor),m_bThreadsEnabled(TRUE),sleepTime(100){ - if(m_bThreadsEnabled){ - addChore(this,ID_CHORE_THREADS); - } +FXRbApp::FXRbApp(const FXchar* appname,const FXchar* vendor) : FXApp(appname,vendor),m_bThreadsEnabled(FALSE),sleepTime(100){ + setThreadsEnabled(TRUE); } @@ -67,7 +73,12 @@ void FXRbApp::setThreadsEnabled(FXbool enabled){ if(enabled){ if(!m_bThreadsEnabled){ m_bThreadsEnabled=TRUE; +#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) + pipe2(interrupt_fds, O_NONBLOCK); + addInput(interrupt_fds[0],INPUT_READ,this,ID_CHORE_THREADS); +#else addChore(this,ID_CHORE_THREADS); +#endif } } else{ @@ -88,9 +99,21 @@ FXuint FXRbApp::getSleepTime() const { return sleepTime; } +long FXRbApp::onChoreThreads(FXObject *obj,FXSelector sel,void *p){ + return FXRbApp_onChoreThreads(this, obj, sel, p); + } + +long FXRbApp_onChoreThreads_gvlcb(FXRbApp *self,FXObject *obj,FXSelector sel,void *p){ + return self->onChoreThreads_gvlcb(obj, sel, p); + } // Process threads -long FXRbApp::onChoreThreads(FXObject*,FXSelector,void*){ +long FXRbApp::onChoreThreads_gvlcb(FXObject*,FXSelector,void*){ +#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) + char byte; + // clear the pipe + read(interrupt_fds[0], &byte, 1); +#else // Pause for 'sleepTime' millseconds struct timeval wait; wait.tv_sec=0; @@ -108,11 +131,17 @@ long FXRbApp::onChoreThreads(FXObject*,FXSelector,void*){ // Re-register this chore for next time addChore(this,ID_CHORE_THREADS); +#endif // Back to work... return 1; } +#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) +void fxrb_wakeup_fox(void *){ + int l = write(FXRbApp::interrupt_fds[1], "X", 1); + } +#endif // Destructor FXRbApp::~FXRbApp(){ diff --git a/ext/fox16_c/include/FXRbApp.h b/ext/fox16_c/include/FXRbApp.h index 17375a245b811d2d1b69a8de6f0aa4a3c0af20e8..68cea6fefe09948379ca1ef354de9fe218e56b20 100644 --- a/ext/fox16_c/include/FXRbApp.h +++ b/ext/fox16_c/include/FXRbApp.h @@ -38,6 +38,9 @@ inline void cls ## _detach(cls *self){ \ inline void cls ## _create(cls *self){ \ self->cls::create(); \ } \ +inline FXint cls ## _run_gvl(cls *self){ \ + return self->cls::run(); \ + } \ static void cls ## _init(cls* self,VALUE ary,bool connect){ \ int i; \ char **argv; \ @@ -114,6 +117,8 @@ class FXRbApp : public FXApp { protected: FXbool m_bThreadsEnabled; FXuint sleepTime; +public: + static int interrupt_fds[2]; protected: FXRbApp(){} public: @@ -126,6 +131,7 @@ public: }; public: long onChoreThreads(FXObject*,FXSelector,void*); + long onChoreThreads_gvlcb(FXObject*,FXSelector,void*); public: // Constructor FXRbApp(const FXchar* name,const FXchar* vendor); @@ -152,4 +158,6 @@ public: virtual ~FXRbApp(); }; +long FXRbApp_onChoreThreads_gvlcb(FXRbApp*,FXObject*,FXSelector,void*); + #endif diff --git a/ext/fox16_c/include/FXRbDialogBox.h b/ext/fox16_c/include/FXRbDialogBox.h index 883b926fad5fb767aa807591cc6dd794e9e97890..4a748a484eacec7d975d96dd554e87582f6d04ed 100644 --- a/ext/fox16_c/include/FXRbDialogBox.h +++ b/ext/fox16_c/include/FXRbDialogBox.h @@ -28,7 +28,7 @@ #define FXRBDIALOGBOX_H #define DECLARE_FXDIALOGBOX_STUBS(klass) \ -inline FXuint klass ## _execute(klass* self,FXuint placement){ \ +inline FXuint klass ## _execute_gvl(klass* self,FXuint placement){ \ return self->klass::execute(placement); \ } diff --git a/ext/fox16_c/include/gvl_wrappers.h b/ext/fox16_c/include/gvl_wrappers.h index df478173992b5472f2250b76f83545c60fc100ce..9013224718ab1d6abcc9853bf9511ae754c1a713 100644 --- a/ext/fox16_c/include/gvl_wrappers.h +++ b/ext/fox16_c/include/gvl_wrappers.h @@ -26,6 +26,8 @@ extern "C" { #endif } +void fxrb_wakeup_fox(void *); + #define DEFINE_PARAM_LIST1(type, ref, name) \ , name @@ -71,7 +73,7 @@ extern __thread int g_fxrb_thread_has_gvl; struct gvl_wrapper_##klass##_##name##_params params = { \ {firstparamname FOR_EACH_PARAM_OF_##baseclass##_##name(DEFINE_PARAM_LIST1)}, when_non_void((rettype)0) \ }; \ - rb_thread_call_without_gvl(gvl_##klass##_##name##_skeleton, ¶ms, RUBY_UBF_IO, 0); \ + rb_thread_call_without_gvl(gvl_##klass##_##name##_skeleton, ¶ms, fxrb_wakeup_fox, 0); \ when_non_void( return params.retval; ) \ } #else @@ -147,6 +149,11 @@ extern __thread int g_fxrb_thread_has_gvl; #define FOR_EACH_PARAM_OF_FXImage_savePixels(param) \ param(FXStream, &, store) +#define FOR_EACH_PARAM_OF_FXDialogBox_execute(param) \ + param(FXuint, , placement) + +#define FOR_EACH_PARAM_OF_FXApp_run(param) + /* function( class, name, baseclass, void_or_nonvoid, returntype, firstparamtype, firstparamname ) */ #define FOR_EACH_BLOCKING_FUNCTION(function) \ function(FXImage, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXImage *, self) \ @@ -200,7 +207,22 @@ extern __thread int g_fxrb_thread_has_gvl; function(FXXBMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXBMIcon *, self) \ function(FXXBMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXBMIcon *, self) \ function(FXXPMIcon, loadPixels, FXImage, GVL_TYPE_NONVOID, bool, FXXPMIcon *, self) \ - function(FXXPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMIcon *, self) + function(FXXPMIcon, savePixels, FXImage, GVL_TYPE_NONVOID, bool, const FXXPMIcon *, self) \ + function(FXChoiceBox, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXChoiceBox *, self) \ + function(FXColorDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXColorDialog *, self) \ + function(FXDialogBox, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXDialogBox *, self) \ + function(FXDirDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXDirDialog *, self) \ + function(FXFileDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXFileDialog *, self) \ + function(FXFontDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXFontDialog *, self) \ + function(FXInputDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXInputDialog *, self) \ + function(FXMessageBox, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXMessageBox *, self) \ + function(FXPrintDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXPrintDialog *, self) \ + function(FXProgressDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXProgressDialog *, self) \ + function(FXReplaceDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXReplaceDialog *, self) \ + function(FXSearchDialog, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXSearchDialog *, self) \ + function(FXWizard, execute, FXDialogBox, GVL_TYPE_NONVOID, FXuint, FXWizard *, self) \ + function(FXApp, run, FXApp, GVL_TYPE_NONVOID, FXint, FXApp *, self) \ + FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL ) @@ -470,6 +492,11 @@ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL ) param(TYPE1, , arg1) \ param(TYPE2, , arg2) +#define FOR_EACH_PARAM_OF_FXRbApp_onChoreThreads_4(param) \ + param(ID, , func) \ + param(TYPE1, , arg1) \ + param(TYPE2, , arg2) + /* function( name, void_or_nonvoid, returntype, firstparamtype, firstparamname, paramcount ) */ #define FOR_EACH_CALLBACK_FUNCTION(function) \ @@ -524,6 +551,7 @@ FOR_EACH_BLOCKING_FUNCTION( DEFINE_GVL_STUB_DECL ) function(FXRbCallDCDrawMethod, GVL_TYPE_VOID, void, RECV, recv, 6) \ function(FXRbCallTreeItemMethod, GVL_TYPE_NONVOID, FXTreeItem*, RECV, recv, 4) \ function(FXRbCallFoldingItemMethod, GVL_TYPE_NONVOID, FXFoldingItem*, RECV, recv, 4) \ + function(FXRbApp_onChoreThreads, GVL_TYPE_NONVOID, long, RECV, recv, 4) \ FOR_EACH_CALLBACK_FUNCTION( DEFINE_GVLCB_STUB_DECL ) diff --git a/lib/fox16/thread.rb b/lib/fox16/thread.rb index 0cf58ee981d904ed92a92259b295ddc468d473bb..902b8e89b681d7ad3082058bb3eb77a2a0bc0617 100644 --- a/lib/fox16/thread.rb +++ b/lib/fox16/thread.rb @@ -24,6 +24,7 @@ module Fox gs = TCPServer.open('localhost', 0) prd = TCPSocket.open('localhost', gs.addr[1]) pwr = gs.accept + gs.close else prd, pwr = IO.pipe end diff --git a/swig-interfaces/FXApp.i b/swig-interfaces/FXApp.i index f25f8b4c7a56aa092c0c2651cbf87f2c2ef134f6..f3aa4b05605f81812e0cd5c9bde163c952b9a741 100644 --- a/swig-interfaces/FXApp.i +++ b/swig-interfaces/FXApp.i @@ -397,12 +397,6 @@ public: /// Perform one event dispatch; return true if event was dispatched bool runOneEvent(bool blocking=true); - /** - * Run the main application event loop until stop() is called, - * and return the exit code passed as argument to stop(). - */ - FXint run(); - /** * Run an event loop till some flag becomes non-zero, and * then return. diff --git a/swig-interfaces/macros.i b/swig-interfaces/macros.i index 8ed1e82dacf4d08357cefa498ff0aaf5995aed04..3349425aeab3a8222d643ff71912f5fa069f6272 100644 --- a/swig-interfaces/macros.i +++ b/swig-interfaces/macros.i @@ -31,6 +31,8 @@ /// Detach application's windows virtual void detach(); + FXint run(); + /** * Initialize application. * Parses and removes common command line arguments, reads the registry.