aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2021-12-31 09:31:27 +0000
committerPo Lu2021-12-31 09:31:27 +0000
commitd1fde0ab8ae53b684ff4ba858f1e270bc3ba9db6 (patch)
treeecbe1b069137190bf014466254955c1e7766b90b /src
parentc452ffe4c28da21991f1f98007fbe1d66c7e0538 (diff)
downloademacs-d1fde0ab8ae53b684ff4ba858f1e270bc3ba9db6.tar.gz
emacs-d1fde0ab8ae53b684ff4ba858f1e270bc3ba9db6.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/haiku_support.cc75
1 files changed, 72 insertions, 3 deletions
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index d211f1157d3..66b0e519b07 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -85,6 +85,13 @@ static key_map *key_map = NULL;
85static char *key_chars = NULL; 85static char *key_chars = NULL;
86static BLocker key_map_lock; 86static BLocker key_map_lock;
87 87
88/* The locking semantics of BWindows running in multiple threads are
89 so complex that child frame state (which is the only state that is
90 shared between different BWindows at runtime) does best with a
91 single global lock. */
92
93static BLocker child_frame_lock;
94
88extern "C" 95extern "C"
89{ 96{
90 extern _Noreturn void emacs_abort (void); 97 extern _Noreturn void emacs_abort (void);
@@ -247,6 +254,8 @@ public:
247 254
248 ~EmacsWindow () 255 ~EmacsWindow ()
249 { 256 {
257 if (!child_frame_lock.Lock ())
258 gui_abort ("Failed to lock child frame state lock");
250 struct child_frame *next; 259 struct child_frame *next;
251 for (struct child_frame *f = subset_windows; f; f = next) 260 for (struct child_frame *f = subset_windows; f; f = next)
252 { 261 {
@@ -257,6 +266,7 @@ public:
257 266
258 if (this->parent) 267 if (this->parent)
259 UnparentAndUnlink (); 268 UnparentAndUnlink ();
269 child_frame_lock.Unlock ();
260 } 270 }
261 271
262 void 272 void
@@ -269,10 +279,13 @@ public:
269 void 279 void
270 UpwardsSubsetChildren (EmacsWindow *w) 280 UpwardsSubsetChildren (EmacsWindow *w)
271 { 281 {
282 if (!child_frame_lock.Lock ())
283 gui_abort ("Failed to lock child frame state lock");
272 UpwardsSubset (w); 284 UpwardsSubset (w);
273 for (struct child_frame *f = subset_windows; f; 285 for (struct child_frame *f = subset_windows; f;
274 f = f->next) 286 f = f->next)
275 f->window->UpwardsSubsetChildren (w); 287 f->window->UpwardsSubsetChildren (w);
288 child_frame_lock.Unlock ();
276 } 289 }
277 290
278 void 291 void
@@ -285,15 +298,20 @@ public:
285 void 298 void
286 UpwardsUnSubsetChildren (EmacsWindow *w) 299 UpwardsUnSubsetChildren (EmacsWindow *w)
287 { 300 {
301 if (!child_frame_lock.Lock ())
302 gui_abort ("Failed to lock child frame state lock");
288 UpwardsUnSubset (w); 303 UpwardsUnSubset (w);
289 for (struct child_frame *f = subset_windows; f; 304 for (struct child_frame *f = subset_windows; f;
290 f = f->next) 305 f = f->next)
291 f->window->UpwardsUnSubsetChildren (w); 306 f->window->UpwardsUnSubsetChildren (w);
307 child_frame_lock.Unlock ();
292 } 308 }
293 309
294 void 310 void
295 Unparent (void) 311 Unparent (void)
296 { 312 {
313 if (!child_frame_lock.Lock ())
314 gui_abort ("Failed to lock child frame state lock");
297 this->SetFeel (B_NORMAL_WINDOW_FEEL); 315 this->SetFeel (B_NORMAL_WINDOW_FEEL);
298 UpwardsUnSubsetChildren (parent); 316 UpwardsUnSubsetChildren (parent);
299 this->RemoveFromSubset (this); 317 this->RemoveFromSubset (this);
@@ -303,13 +321,17 @@ public:
303 fullscreen_p = 0; 321 fullscreen_p = 0;
304 MakeFullscreen (1); 322 MakeFullscreen (1);
305 } 323 }
324 child_frame_lock.Unlock ();
306 } 325 }
307 326
308 void 327 void
309 UnparentAndUnlink (void) 328 UnparentAndUnlink (void)
310 { 329 {
330 if (!child_frame_lock.Lock ())
331 gui_abort ("Failed to lock child frame state lock");
311 this->parent->UnlinkChild (this); 332 this->parent->UnlinkChild (this);
312 this->Unparent (); 333 this->Unparent ();
334 child_frame_lock.Unlock ();
313 } 335 }
314 336
315 void 337 void
@@ -337,6 +359,9 @@ public:
337 void 359 void
338 ParentTo (EmacsWindow *window) 360 ParentTo (EmacsWindow *window)
339 { 361 {
362 if (!child_frame_lock.Lock ())
363 gui_abort ("Failed to lock child frame state lock");
364
340 if (this->parent) 365 if (this->parent)
341 UnparentAndUnlink (); 366 UnparentAndUnlink ();
342 367
@@ -352,6 +377,8 @@ public:
352 } 377 }
353 this->Sync (); 378 this->Sync ();
354 window->LinkChild (this); 379 window->LinkChild (this);
380
381 child_frame_lock.Unlock ();
355 } 382 }
356 383
357 void 384 void
@@ -393,6 +420,9 @@ public:
393 MoveChild (EmacsWindow *window, int xoff, int yoff, 420 MoveChild (EmacsWindow *window, int xoff, int yoff,
394 int weak_p) 421 int weak_p)
395 { 422 {
423 if (!child_frame_lock.Lock ())
424 gui_abort ("Failed to lock child frame state lock");
425
396 for (struct child_frame *f = subset_windows; f; 426 for (struct child_frame *f = subset_windows; f;
397 f = f->next) 427 f = f->next)
398 { 428 {
@@ -402,10 +432,13 @@ public:
402 f->yoff = yoff; 432 f->yoff = yoff;
403 if (!weak_p) 433 if (!weak_p)
404 DoMove (f); 434 DoMove (f);
435
436 child_frame_lock.Unlock ();
405 return; 437 return;
406 } 438 }
407 } 439 }
408 440
441 child_frame_lock.Unlock ();
409 gui_abort ("Trying to move a child frame that doesn't exist"); 442 gui_abort ("Trying to move a child frame that doesn't exist");
410 } 443 }
411 444
@@ -606,9 +639,14 @@ public:
606 639
607 haiku_write (MOVE_EVENT, &rq); 640 haiku_write (MOVE_EVENT, &rq);
608 641
642 if (!child_frame_lock.Lock ())
643 gui_abort ("Failed to lock child frame state lock");
644
609 for (struct child_frame *f = subset_windows; 645 for (struct child_frame *f = subset_windows;
610 f; f = f->next) 646 f; f = f->next)
611 DoMove (f); 647 DoMove (f);
648
649 child_frame_lock.Unlock ();
612 BWindow::FrameMoved (newPosition); 650 BWindow::FrameMoved (newPosition);
613 } 651 }
614 652
@@ -623,10 +661,14 @@ public:
623 void 661 void
624 EmacsMoveTo (int x, int y) 662 EmacsMoveTo (int x, int y)
625 { 663 {
664 if (!child_frame_lock.Lock ())
665 gui_abort ("Failed to lock child frame state lock");
666
626 if (!this->parent) 667 if (!this->parent)
627 this->MoveTo (x, y); 668 this->MoveTo (x, y);
628 else 669 else
629 this->parent->MoveChild (this, x, y, 0); 670 this->parent->MoveChild (this, x, y, 0);
671 child_frame_lock.Unlock ();
630 } 672 }
631 673
632 bool 674 bool
@@ -654,9 +696,14 @@ public:
654 { 696 {
655 if (this->IsHidden ()) 697 if (this->IsHidden ())
656 return; 698 return;
699 if (!child_frame_lock.Lock ())
700 gui_abort ("Failed to lock child frame state lock");
701
657 Hide (); 702 Hide ();
658 if (this->parent) 703 if (this->parent)
659 UpwardsUnSubsetChildren (this->parent); 704 UpwardsUnSubsetChildren (this->parent);
705
706 child_frame_lock.Unlock ();
660 } 707 }
661 708
662 void 709 void
@@ -664,11 +711,17 @@ public:
664 { 711 {
665 if (!this->IsHidden ()) 712 if (!this->IsHidden ())
666 return; 713 return;
714
715 if (!child_frame_lock.Lock ())
716 gui_abort ("Failed to lock child frame state lock");
717
667 if (this->parent) 718 if (this->parent)
668 shown_flag = 1; 719 shown_flag = 1;
669 Show (); 720 Show ();
670 if (this->parent) 721 if (this->parent)
671 UpwardsSubsetChildren (this->parent); 722 UpwardsSubsetChildren (this->parent);
723
724 child_frame_lock.Unlock ();
672 } 725 }
673 726
674 void 727 void
@@ -719,6 +772,9 @@ public:
719 void 772 void
720 GetParentWidthHeight (int *width, int *height) 773 GetParentWidthHeight (int *width, int *height)
721 { 774 {
775 if (!child_frame_lock.Lock ())
776 gui_abort ("Failed to lock child frame state lock");
777
722 if (parent) 778 if (parent)
723 { 779 {
724 *width = parent->Frame ().Width (); 780 *width = parent->Frame ().Width ();
@@ -730,11 +786,16 @@ public:
730 *width = s.Frame ().Width (); 786 *width = s.Frame ().Width ();
731 *height = s.Frame ().Height (); 787 *height = s.Frame ().Height ();
732 } 788 }
789
790 child_frame_lock.Unlock ();
733 } 791 }
734 792
735 void 793 void
736 OffsetChildRect (BRect *r, EmacsWindow *c) 794 OffsetChildRect (BRect *r, EmacsWindow *c)
737 { 795 {
796 if (!child_frame_lock.Lock ())
797 gui_abort ("Failed to lock child frame state lock");
798
738 for (struct child_frame *f; f; f = f->next) 799 for (struct child_frame *f; f; f = f->next)
739 if (f->window == c) 800 if (f->window == c)
740 { 801 {
@@ -742,9 +803,11 @@ public:
742 r->bottom -= f->yoff; 803 r->bottom -= f->yoff;
743 r->left -= f->xoff; 804 r->left -= f->xoff;
744 r->right -= f->xoff; 805 r->right -= f->xoff;
806 child_frame_lock.Unlock ();
745 return; 807 return;
746 } 808 }
747 809
810 child_frame_lock.Lock ();
748 gui_abort ("Trying to calculate offsets for a child frame that doesn't exist"); 811 gui_abort ("Trying to calculate offsets for a child frame that doesn't exist");
749 } 812 }
750 813
@@ -753,8 +816,8 @@ public:
753 { 816 {
754 BScreen screen (this); 817 BScreen screen (this);
755 818
756 if (!screen.IsValid ()) 819 if (!screen.IsValid ())
757 gui_abort ("Trying to make a window fullscreen without a screen"); 820 gui_abort ("Trying to make a window fullscreen without a screen");
758 821
759 if (make_fullscreen_p == fullscreen_p) 822 if (make_fullscreen_p == fullscreen_p)
760 return; 823 return;
@@ -768,9 +831,15 @@ public:
768 831
769 flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE; 832 flags |= B_NOT_MOVABLE | B_NOT_ZOOMABLE;
770 pre_fullscreen_rect = Frame (); 833 pre_fullscreen_rect = Frame ();
834
835 if (!child_frame_lock.Lock ())
836 gui_abort ("Failed to lock child frame state lock");
837
771 if (parent) 838 if (parent)
772 parent->OffsetChildRect (&pre_fullscreen_rect, this); 839 parent->OffsetChildRect (&pre_fullscreen_rect, this);
773 840
841 child_frame_lock.Unlock ();
842
774 int w, h; 843 int w, h;
775 EmacsMoveTo (0, 0); 844 EmacsMoveTo (0, 0);
776 GetParentWidthHeight (&w, &h); 845 GetParentWidthHeight (&w, &h);
@@ -1065,7 +1134,7 @@ public:
1065 if (looper_locked_count) 1134 if (looper_locked_count)
1066 { 1135 {
1067 if (!offscreen_draw_bitmap_1->Lock ()) 1136 if (!offscreen_draw_bitmap_1->Lock ())
1068 gui_abort ("Failed to lock bitmap after double buffering was set up."); 1137 gui_abort ("Failed to lock bitmap after double buffering was set up");
1069 } 1138 }
1070 1139
1071 UnlockLooper (); 1140 UnlockLooper ();