From 13dbe1dd98906b0f2007de62439b02642ef367da Mon Sep 17 00:00:00 2001 From: cxl Date: Sat, 26 Jan 2013 19:23:41 +0000 Subject: [PATCH] CtrlCore: X11 and GTK MT fixes (#429) git-svn-id: svn://ultimatepp.org/upp/trunk@5735 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Random.cpp | 1 + uppsrc/Core/Vcont.h | 1 + uppsrc/Core/Vcont.hpp | 14 ++++++++++++++ uppsrc/Core/src.tpp/Vector$en-us.tpp | 10 +++++++++- uppsrc/CtrlCore/CtrlMt.cpp | 14 +++++++++----- uppsrc/CtrlCore/GtkAfter.h | 2 ++ uppsrc/CtrlCore/GtkApp.cpp | 14 ++++++++++++++ uppsrc/CtrlCore/GtkCreate.cpp | 13 ++++++++++++- uppsrc/CtrlCore/GtkCtrl.cpp | 2 +- uppsrc/CtrlCore/GtkCtrl.h | 2 ++ uppsrc/CtrlCore/GtkEvent.cpp | 11 ++++++++--- uppsrc/CtrlCore/GtkWnd.cpp | 2 +- uppsrc/CtrlCore/GtkX11Util.cpp | 3 +-- uppsrc/CtrlCore/X11App.cpp | 3 +++ 14 files changed, 78 insertions(+), 14 deletions(-) diff --git a/uppsrc/Core/Random.cpp b/uppsrc/Core/Random.cpp index 8f1d46274..42f34453a 100644 --- a/uppsrc/Core/Random.cpp +++ b/uppsrc/Core/Random.cpp @@ -210,6 +210,7 @@ dword Random() dword Random(dword n) { + ASSERT(n); dword mask = n; mask |= mask >> 1; mask |= mask >> 2; diff --git a/uppsrc/Core/Vcont.h b/uppsrc/Core/Vcont.h index c7ee3b658..3b6c6b409 100644 --- a/uppsrc/Core/Vcont.h +++ b/uppsrc/Core/Vcont.h @@ -76,6 +76,7 @@ public: void Insert(int i, const Vector& x); void Insert(int i, const Vector& x, int offset, int count); void InsertPick(int i, pick_ Vector& x); + void InsertSplit(int i, Vector& v, int from); void Append(const Vector& x) { Insert(GetCount(), x); } void Append(const Vector& x, int o, int c) { Insert(GetCount(), x, o, c); } void AppendPick(pick_ Vector& x) { InsertPick(GetCount(), x); } diff --git a/uppsrc/Core/Vcont.hpp b/uppsrc/Core/Vcont.hpp index cca395612..7c0eec80b 100644 --- a/uppsrc/Core/Vcont.hpp +++ b/uppsrc/Core/Vcont.hpp @@ -308,6 +308,20 @@ void Vector::InsertPick(int i, pick_ Vector& v) { SetPicked(v); } +template +void Vector::InsertSplit(int i, Vector& v, int from) +{ + Chk(); + v.Chk(); + ASSERT(!vector || v.vector != vector && from <= v.GetCount()); + int n = v.GetCount() - from; + if(n) { + RawInsert(i, n); + memcpy(vector + i, v.vector + from, sizeof(T) * n); + } + v.Trim(from); +} + template void Vector::Set(int i, const T& x, int count) { Chk(); diff --git a/uppsrc/Core/src.tpp/Vector$en-us.tpp b/uppsrc/Core/src.tpp/Vector$en-us.tpp index bfd9da4d6..a664ef8ec 100644 --- a/uppsrc/Core/src.tpp/Vector$en-us.tpp +++ b/uppsrc/Core/src.tpp/Vector$en-us.tpp @@ -354,6 +354,14 @@ copy constructor for T, but destroys source Vector.&] [s7; [*C@3 x]-|Source Vector.&] [s3;%- &] [s4;%- &] +[s5;:Vector`:`:InsertSplit`(int`,Vector``&`,int`):%- [@(0.0.255) void]_[* InsertSplit +]([@(0.0.255) int]_[*@3 i], [_^Vector^ Vector]<[*@4 T]>`&_[*@3 v], [@(0.0.255) int]_[*@3 from]) +&] +[s2; Insert the part of source vector [%-*@3 v] starting at element +[%-*@3 from] till the end at position [%-*@3 i] and trims [%-*@3 v] +at [%-*@3 from], effectively splitting [%-*@3 v] into two parts.&] +[s3; &] +[s4;%- &] [s5;:Vector`:`:Append`(const Vector`&`):%- [@(0.0.255) void]_[* Append]([@(0.0.255) const]_ [_^Vector^ Vector][@(0.0.255) `&]_[*@3 x])&] [s2; Appends all elements of source Vector.&] @@ -538,4 +546,4 @@ simple constant time operation.&] [s7; [*C@3 a]-|First Vector to swap.&] [s7; [*C@3 b]-|Second Vector to swap.&] [s3; &] -[s0; ] \ No newline at end of file +[s0; ]] \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlMt.cpp b/uppsrc/CtrlCore/CtrlMt.cpp index 321ebc804..7ba273cd3 100644 --- a/uppsrc/CtrlCore/CtrlMt.cpp +++ b/uppsrc/CtrlCore/CtrlMt.cpp @@ -1,6 +1,6 @@ #include "CtrlCore.h" -#define LLOG(x) // DLOG(x) +#define LLOG(x) // DLOG(x) NAMESPACE_UPP @@ -12,37 +12,41 @@ static thread__ int sGLockLevel = 0; void EnterGuiMutex() { + LLOG(">EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread()); if(sGLockLevel++ == 0) sGLock.Enter(); - LLOG("EnterGuiMutex " << sGLockLevel); + LLOG("EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread()); } void EnterGuiMutex(int n) { + LLOG(">EnterGuiMutex: " << n << ' ' << sGLockLevel << ' ' << IsMainThread()); if(n > 0) { if(sGLockLevel == 0) sGLock.Enter(); sGLockLevel += n; } - LLOG("EnterGuiMutex " << sGLockLevel); + LLOG("EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread()); } void LeaveGuiMutex() { + LLOG(">LeaveGuiMutex " << sGLockLevel << ' ' << IsMainThread()); ASSERT(sGLockLevel > 0); if(--sGLockLevel == 0) sGLock.Leave(); - LLOG("LeaveGuiMutex " << sGLockLevel); + LLOG("LeaveGuiMutex " << sGLockLevel << ' ' << IsMainThread()); } int LeaveGuiMutexAll() { + LLOG(">LeaveGuiMutexAll " << sGLockLevel << ' ' << IsMainThread()); int q = sGLockLevel; if(q) { sGLock.Leave(); sGLockLevel = 0; } - LLOG("LeaveGuiMutex all " << q); + LLOG("LeaveGuiMutexAll " << q << ' ' << IsMainThread()); return q; } diff --git a/uppsrc/CtrlCore/GtkAfter.h b/uppsrc/CtrlCore/GtkAfter.h index 8b374b892..b93758325 100644 --- a/uppsrc/CtrlCore/GtkAfter.h +++ b/uppsrc/CtrlCore/GtkAfter.h @@ -9,6 +9,7 @@ void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f); class DHCtrl : Ctrl {}; void InitGtkApp(int argc, char **argv, const char **envptr); +void ExitGtkApp(); #define GUI_APP_MAIN \ void GuiMainFn_(); \ @@ -18,6 +19,7 @@ int main(int argc, char **argv, const char **envptr) { \ UPP::InitGtkApp(argc, argv, envptr); \ GuiMainFn_(); \ UPP::Ctrl::CloseTopCtrls(); \ + ExitGtkApp(); \ UPP::AppExit__(); \ return UPP::GetExitCode(); \ } \ diff --git a/uppsrc/CtrlCore/GtkApp.cpp b/uppsrc/CtrlCore/GtkApp.cpp index da09dbba7..3bf89819e 100644 --- a/uppsrc/CtrlCore/GtkApp.cpp +++ b/uppsrc/CtrlCore/GtkApp.cpp @@ -25,6 +25,13 @@ void Ctrl::PanicMsgBox(const char *title, const char *text) void InitGtkApp(int argc, char **argv, const char **envptr) { LLOG(rmsecs() << " InitGtkApp"); +#ifdef _MULTITHREADED + if(!g_thread_supported()) + g_thread_init( NULL ); + gdk_threads_set_lock_functions(EnterGuiMutex, LeaveGuiMutex); + gdk_threads_init(); + EnterGuiMutex(); +#endif gtk_init(&argc, &argv); Ctrl::GlobalBackBuffer(); Ctrl::ReSkin(); @@ -33,6 +40,13 @@ void InitGtkApp(int argc, char **argv, const char **envptr) gdk_window_add_filter(NULL, Ctrl::RootKeyFilter, NULL); } +void ExitGtkApp() +{ +#ifdef _MULTITHREADED + LeaveGuiMutex(); +#endif +} + END_UPP_NAMESPACE #endif diff --git a/uppsrc/CtrlCore/GtkCreate.cpp b/uppsrc/CtrlCore/GtkCreate.cpp index 73a6431bf..7511d92ef 100644 --- a/uppsrc/CtrlCore/GtkCreate.cpp +++ b/uppsrc/CtrlCore/GtkCreate.cpp @@ -4,9 +4,15 @@ NAMESPACE_UPP -#define LLOG(x) // DLOG(x) +#define LLOG(x) // DLOG(x) void Ctrl::Create(Ctrl *owner, bool popup) +{ + LLOG("Create Call"); + Call(callback2(this, &Ctrl::Create0, owner, popup)); +} + +void Ctrl::Create0(Ctrl *owner, bool popup) { GuiLock __; ASSERT(IsMainThread()); @@ -106,6 +112,11 @@ void Ctrl::GuiPlatformRemove() } void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) +{ + Call(callback2(this, &Ctrl::PopUp0, owner, activate)); +} + +void Ctrl::PopUp0(Ctrl *owner, bool activate) { GuiLock __; LLOG("POPUP " << Name() << ", " << GetRect() << ", activate " << activate); diff --git a/uppsrc/CtrlCore/GtkCtrl.cpp b/uppsrc/CtrlCore/GtkCtrl.cpp index de8e82254..f71711b6b 100644 --- a/uppsrc/CtrlCore/GtkCtrl.cpp +++ b/uppsrc/CtrlCore/GtkCtrl.cpp @@ -2,7 +2,7 @@ #ifdef GUI_GTK -#define LLOG(x) // DLOG(x) +#define LLOG(x) DLOG(x) NAMESPACE_UPP diff --git a/uppsrc/CtrlCore/GtkCtrl.h b/uppsrc/CtrlCore/GtkCtrl.h index 990a43db9..9c5516afa 100644 --- a/uppsrc/CtrlCore/GtkCtrl.h +++ b/uppsrc/CtrlCore/GtkCtrl.h @@ -1,5 +1,7 @@ //$ class Ctrl { + void Create0(Ctrl *owner, bool popup); void Create(Ctrl *owner, bool popup); + void PopUp0(Ctrl *owner, bool activate); static gboolean GtkProc(GtkWidget *widget, GdkEvent *event, gpointer user_data); static void IMCommit(GtkIMContext *context, gchar *str, gpointer user_data); diff --git a/uppsrc/CtrlCore/GtkEvent.cpp b/uppsrc/CtrlCore/GtkEvent.cpp index eb9b3c832..1a9b161e1 100644 --- a/uppsrc/CtrlCore/GtkEvent.cpp +++ b/uppsrc/CtrlCore/GtkEvent.cpp @@ -4,7 +4,7 @@ NAMESPACE_UPP -#define LLOG(x) // DLOG(rmsecs() << ' ' << x) +#define LLOG(x) // DLOG(rmsecs() << ' ' << x) // #define LOG_EVENTS _DBG_ bool Ctrl::EventMouseValid; @@ -91,6 +91,7 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data) ev = f->b; LOG(rmsecs() << " FETCH EVENT " << ev); #endif + GuiLock __; GdkEventKey *key; bool pressed = false; bool retval = true; @@ -273,13 +274,17 @@ void Ctrl::AddEvent(gpointer user_data, int type, const Value& value) void Ctrl::IMCommit(GtkIMContext *context, gchar *str, gpointer user_data) { + GuiLock __; AddEvent(user_data, EVENT_TEXT, FromUtf8(str)); } void Ctrl::FetchEvents(bool may_block) { + LLOG("FetchEvents " << may_block); + int level = LeaveGuiMutexAll(); while(g_main_context_iteration(NULL, may_block)) may_block = false; + EnterGuiMutex(level); } bool Ctrl::IsWaitingEvent0(bool fetch) @@ -591,8 +596,8 @@ void Ctrl::EventLoop0(Ctrl *ctrl) ctrl->inloop = true; } - while(!IsEndSession() && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) - { + while(!IsEndSession() && + (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) { FetchEvents(TRUE); ProcessEvents(); } diff --git a/uppsrc/CtrlCore/GtkWnd.cpp b/uppsrc/CtrlCore/GtkWnd.cpp index c42d6439d..ae763634a 100644 --- a/uppsrc/CtrlCore/GtkWnd.cpp +++ b/uppsrc/CtrlCore/GtkWnd.cpp @@ -4,7 +4,7 @@ NAMESPACE_UPP -#define LLOG(x) // DLOG(rmsecs() << ' ' << x) +#define LLOG(x) // DLOG(rmsecs() << ' ' << x) Vector Ctrl::hotkey; Vector Ctrl::keyhot; diff --git a/uppsrc/CtrlCore/GtkX11Util.cpp b/uppsrc/CtrlCore/GtkX11Util.cpp index 915976827..c9f78c630 100644 --- a/uppsrc/CtrlCore/GtkX11Util.cpp +++ b/uppsrc/CtrlCore/GtkX11Util.cpp @@ -32,7 +32,7 @@ Window Xroot() String GetProperty(Window w, Atom property, Atom rtype) { - GuiLock __; + GuiLock __; String result; int format; unsigned long nitems, after = 1; @@ -40,7 +40,6 @@ String GetProperty(Window w, Atom property, Atom rtype) Atom type = None; unsigned char *data; long rsize = minmax((long)(XMaxRequestSize(Xdisplay()) - 100), (long)256, (long)65536); - while(after > 0) { if(XGetWindowProperty(Xdisplay(), w, property, offset, rsize, 0, rtype, &type, &format, &nitems, &after, &data) != Success) diff --git a/uppsrc/CtrlCore/X11App.cpp b/uppsrc/CtrlCore/X11App.cpp index 9d3b987b8..98ebcc617 100644 --- a/uppsrc/CtrlCore/X11App.cpp +++ b/uppsrc/CtrlCore/X11App.cpp @@ -400,6 +400,9 @@ void Ctrl::InstallPanicBox() void Ctrl::InitX11(const char *display) { GuiLock __; + + XInitThreads(); + InstallPanicMessageBox(sPanicMessageBox); InitX11Draw(display);