mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Use a single global lock for the child frame state on Haiku
Each BWindows (and various system callbacks) runs in a separate thread, so there are very complicated locking semantics that used to be handled manually. This changes child frame state to use a single global lock, which makes things much easier. * src/haiku_support.cc (child_frame_lock): New variable. (class EmacsWindow): (~EmacsWindow): (Unparent): (ParentTo): (MoveChild): (FrameMoved): (EmacsHide): (EmacsShow): (GetParentWidthHeight): (OffsetChildRect): (MakeFullscreen): (SetUpDoubleBuffering): Use a single lock for controlling access to child frame state.
This commit is contained in:
parent
c452ffe4c2
commit
d1fde0ab8a
1 changed files with 72 additions and 3 deletions
|
|
@ -85,6 +85,13 @@ static key_map *key_map = NULL;
|
|||
static char *key_chars = NULL;
|
||||
static BLocker key_map_lock;
|
||||
|
||||
/* The locking semantics of BWindows running in multiple threads are
|
||||
so complex that child frame state (which is the only state that is
|
||||
shared between different BWindows at runtime) does best with a
|
||||
single global lock. */
|
||||
|
||||
static BLocker child_frame_lock;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern _Noreturn void emacs_abort (void);
|
||||
|
|
@ -247,6 +254,8 @@ class EmacsWindow : public BWindow
|
|||
|
||||
~EmacsWindow ()
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
struct child_frame *next;
|
||||
for (struct child_frame *f = subset_windows; f; f = next)
|
||||
{
|
||||
|
|
@ -257,6 +266,7 @@ class EmacsWindow : public BWindow
|
|||
|
||||
if (this->parent)
|
||||
UnparentAndUnlink ();
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -269,10 +279,13 @@ class EmacsWindow : public BWindow
|
|||
void
|
||||
UpwardsSubsetChildren (EmacsWindow *w)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
UpwardsSubset (w);
|
||||
for (struct child_frame *f = subset_windows; f;
|
||||
f = f->next)
|
||||
f->window->UpwardsSubsetChildren (w);
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -285,15 +298,20 @@ class EmacsWindow : public BWindow
|
|||
void
|
||||
UpwardsUnSubsetChildren (EmacsWindow *w)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
UpwardsUnSubset (w);
|
||||
for (struct child_frame *f = subset_windows; f;
|
||||
f = f->next)
|
||||
f->window->UpwardsUnSubsetChildren (w);
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
Unparent (void)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
this->SetFeel (B_NORMAL_WINDOW_FEEL);
|
||||
UpwardsUnSubsetChildren (parent);
|
||||
this->RemoveFromSubset (this);
|
||||
|
|
@ -303,13 +321,17 @@ class EmacsWindow : public BWindow
|
|||
fullscreen_p = 0;
|
||||
MakeFullscreen (1);
|
||||
}
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
UnparentAndUnlink (void)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
this->parent->UnlinkChild (this);
|
||||
this->Unparent ();
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -337,6 +359,9 @@ class EmacsWindow : public BWindow
|
|||
void
|
||||
ParentTo (EmacsWindow *window)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (this->parent)
|
||||
UnparentAndUnlink ();
|
||||
|
||||
|
|
@ -352,6 +377,8 @@ class EmacsWindow : public BWindow
|
|||
}
|
||||
this->Sync ();
|
||||
window->LinkChild (this);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -393,6 +420,9 @@ class EmacsWindow : public BWindow
|
|||
MoveChild (EmacsWindow *window, int xoff, int yoff,
|
||||
int weak_p)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
for (struct child_frame *f = subset_windows; f;
|
||||
f = f->next)
|
||||
{
|
||||
|
|
@ -402,10 +432,13 @@ class EmacsWindow : public BWindow
|
|||
f->yoff = yoff;
|
||||
if (!weak_p)
|
||||
DoMove (f);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
gui_abort ("Trying to move a child frame that doesn't exist");
|
||||
}
|
||||
|
||||
|
|
@ -606,9 +639,14 @@ class EmacsWindow : public BWindow
|
|||
|
||||
haiku_write (MOVE_EVENT, &rq);
|
||||
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
for (struct child_frame *f = subset_windows;
|
||||
f; f = f->next)
|
||||
DoMove (f);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
BWindow::FrameMoved (newPosition);
|
||||
}
|
||||
|
||||
|
|
@ -623,10 +661,14 @@ class EmacsWindow : public BWindow
|
|||
void
|
||||
EmacsMoveTo (int x, int y)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (!this->parent)
|
||||
this->MoveTo (x, y);
|
||||
else
|
||||
this->parent->MoveChild (this, x, y, 0);
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -654,9 +696,14 @@ class EmacsWindow : public BWindow
|
|||
{
|
||||
if (this->IsHidden ())
|
||||
return;
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
Hide ();
|
||||
if (this->parent)
|
||||
UpwardsUnSubsetChildren (this->parent);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -664,11 +711,17 @@ class EmacsWindow : public BWindow
|
|||
{
|
||||
if (!this->IsHidden ())
|
||||
return;
|
||||
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (this->parent)
|
||||
shown_flag = 1;
|
||||
Show ();
|
||||
if (this->parent)
|
||||
UpwardsSubsetChildren (this->parent);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -719,6 +772,9 @@ class EmacsWindow : public BWindow
|
|||
void
|
||||
GetParentWidthHeight (int *width, int *height)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (parent)
|
||||
{
|
||||
*width = parent->Frame ().Width ();
|
||||
|
|
@ -730,11 +786,16 @@ class EmacsWindow : public BWindow
|
|||
*width = s.Frame ().Width ();
|
||||
*height = s.Frame ().Height ();
|
||||
}
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
OffsetChildRect (BRect *r, EmacsWindow *c)
|
||||
{
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
for (struct child_frame *f; f; f = f->next)
|
||||
if (f->window == c)
|
||||
{
|
||||
|
|
@ -742,9 +803,11 @@ class EmacsWindow : public BWindow
|
|||
r->bottom -= f->yoff;
|
||||
r->left -= f->xoff;
|
||||
r->right -= f->xoff;
|
||||
child_frame_lock.Unlock ();
|
||||
return;
|
||||
}
|
||||
|
||||
child_frame_lock.Lock ();
|
||||
gui_abort ("Trying to calculate offsets for a child frame that doesn't exist");
|
||||
}
|
||||
|
||||
|
|
@ -753,8 +816,8 @@ class EmacsWindow : public BWindow
|
|||
{
|
||||
BScreen screen (this);
|
||||
|
||||
if (!screen.IsValid ())
|
||||
gui_abort ("Trying to make a window fullscreen without a screen");
|
||||
if (!screen.IsValid ())
|
||||
gui_abort ("Trying to make a window fullscreen without a screen");
|
||||
|
||||
if (make_fullscreen_p == fullscreen_p)
|
||||
return;
|
||||
|
|
@ -768,9 +831,15 @@ class EmacsWindow : public BWindow
|
|||
|
||||
flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE;
|
||||
pre_fullscreen_rect = Frame ();
|
||||
|
||||
if (!child_frame_lock.Lock ())
|
||||
gui_abort ("Failed to lock child frame state lock");
|
||||
|
||||
if (parent)
|
||||
parent->OffsetChildRect (&pre_fullscreen_rect, this);
|
||||
|
||||
child_frame_lock.Unlock ();
|
||||
|
||||
int w, h;
|
||||
EmacsMoveTo (0, 0);
|
||||
GetParentWidthHeight (&w, &h);
|
||||
|
|
@ -1065,7 +1134,7 @@ class EmacsView : public BView
|
|||
if (looper_locked_count)
|
||||
{
|
||||
if (!offscreen_draw_bitmap_1->Lock ())
|
||||
gui_abort ("Failed to lock bitmap after double buffering was set up.");
|
||||
gui_abort ("Failed to lock bitmap after double buffering was set up");
|
||||
}
|
||||
|
||||
UnlockLooper ();
|
||||
|
|
|
|||
Loading…
Reference in a new issue