CtrlCore: X11 and GTK MT fixes (#429)

git-svn-id: svn://ultimatepp.org/upp/trunk@5735 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2013-01-26 19:23:41 +00:00
parent 688ab69301
commit 13dbe1dd98
14 changed files with 78 additions and 14 deletions

View file

@ -210,6 +210,7 @@ dword Random()
dword Random(dword n)
{
ASSERT(n);
dword mask = n;
mask |= mask >> 1;
mask |= mask >> 2;

View file

@ -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<T>& 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); }

View file

@ -308,6 +308,20 @@ void Vector<T>::InsertPick(int i, pick_ Vector<T>& v) {
SetPicked(v);
}
template <class T>
void Vector<T>::InsertSplit(int i, Vector<T>& 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 <class T>
void Vector<T>::Set(int i, const T& x, int count) {
Chk();

View file

@ -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`<T`>`&`,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; ]
[s0; ]]

View file

@ -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;
}

View file

@ -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(); \
} \

View file

@ -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

View file

@ -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);

View file

@ -2,7 +2,7 @@
#ifdef GUI_GTK
#define LLOG(x) // DLOG(x)
#define LLOG(x) DLOG(x)
NAMESPACE_UPP

View file

@ -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);

View file

@ -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();
}

View file

@ -4,7 +4,7 @@
NAMESPACE_UPP
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
#define LLOG(x) // DLOG(rmsecs() << ' ' << x)
Vector<Callback> Ctrl::hotkey;
Vector<dword> Ctrl::keyhot;

View file

@ -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)

View file

@ -400,6 +400,9 @@ void Ctrl::InstallPanicBox()
void Ctrl::InitX11(const char *display)
{
GuiLock __;
XInitThreads();
InstallPanicMessageBox(sPanicMessageBox);
InitX11Draw(display);