diff --git a/headers/os/interface/MenuBar.h b/headers/os/interface/MenuBar.h index c5dba71bac..b48c91aed9 100644 --- a/headers/os/interface/MenuBar.h +++ b/headers/os/interface/MenuBar.h @@ -106,7 +106,7 @@ private: menu_bar_border fBorder; thread_id fTrackingPID; int32 fPrevFocusToken; - uint32 _reserved1; + sem_id fMenuSem; BRect* fLastBounds; uint32 fBorders; uint32 _reserved[1]; diff --git a/src/kits/interface/MenuBar.cpp b/src/kits/interface/MenuBar.cpp index bce90cb66c..19fd364dce 100644 --- a/src/kits/interface/MenuBar.cpp +++ b/src/kits/interface/MenuBar.cpp @@ -52,6 +52,7 @@ BMenuBar::BMenuBar(BRect frame, const char* name, uint32 resizingMode, fBorder(B_BORDER_FRAME), fTrackingPID(-1), fPrevFocusToken(-1), + fMenuSem(-1), fLastBounds(NULL), fTracking(false) { @@ -67,6 +68,7 @@ BMenuBar::BMenuBar(const char* name, menu_layout layout, uint32 flags) fBorder(B_BORDER_FRAME), fTrackingPID(-1), fPrevFocusToken(-1), + fMenuSem(-1), fLastBounds(NULL), fTracking(false) { @@ -80,6 +82,7 @@ BMenuBar::BMenuBar(BMessage* archive) fBorder(B_BORDER_FRAME), fTrackingPID(-1), fPrevFocusToken(-1), + fMenuSem(-1), fLastBounds(NULL), fTracking(false) { @@ -489,8 +492,9 @@ BMenuBar::StartMenuBar(int32 menuIndex, bool sticky, bool showMenu, // so let's call MenusBeginning() directly window->MenusBeginning(); - sem_id sem = create_sem(0, "window close sem"); - _set_menu_sem_(window, sem); + fMenuSem = create_sem(0, "window close sem"); + _set_menu_sem_(window, fMenuSem); + fTrackingPID = spawn_thread(_TrackTask, "menu_tracking", B_DISPLAY_PRIORITY, NULL); if (fTrackingPID >= 0) { menubar_data data; @@ -507,6 +511,7 @@ BMenuBar::StartMenuBar(int32 menuIndex, bool sticky, bool showMenu, } else { fTracking = false; _set_menu_sem_(window, B_NO_MORE_SEMS); + delete_sem(fMenuSem); } } @@ -534,6 +539,8 @@ BMenuBar::_TrackTask(void* arg) window->PostMessage(_MENUS_DONE_); _set_menu_sem_(window, B_BAD_SEM_ID); + delete_sem(menuBar->fMenuSem); + menuBar->fMenuSem = B_BAD_SEM_ID; return 0; } diff --git a/src/kits/interface/PopUpMenu.cpp b/src/kits/interface/PopUpMenu.cpp index 761d1f52f5..85b9edd931 100644 --- a/src/kits/interface/PopUpMenu.cpp +++ b/src/kits/interface/PopUpMenu.cpp @@ -370,6 +370,7 @@ BPopUpMenu::_Go(BPoint where, bool autoInvoke, bool startOpened, fTrackThread = spawn_thread(_thread_entry, "popup", B_DISPLAY_PRIORITY, data); if (fTrackThread < B_OK) { // Something went wrong. Cleanup and return NULL + delete_sem(sem); if (async && window != NULL) _set_menu_sem_(window, B_BAD_SEM_ID); delete data; @@ -403,6 +404,8 @@ BPopUpMenu::_thread_entry(void* menuData) if (data->async && data->window) _set_menu_sem_(data->window, B_BAD_SEM_ID); + delete_sem(data->lock); + // Commit suicide if needed if (data->async && menu->fAutoDestruct) { menu->fTrackThread = -1; @@ -459,12 +462,8 @@ BPopUpMenu::_WaitMenu(void* _data) BWindow* window = data->window; sem_id sem = data->lock; if (window != NULL) { - status_t err; - do { - err = acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, 50000); - } while (err == B_INTERRUPTED); - - window->UpdateIfNeeded(); + while (acquire_sem_etc(sem, 1, B_RELATIVE_TIMEOUT, 50000) != B_BAD_SEM_ID) + window->UpdateIfNeeded(); } status_t unused; diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 8adf142e7c..c652ff7d18 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -217,23 +217,8 @@ static value_info sWindowValueInfo[] = { void _set_menu_sem_(BWindow* window, sem_id sem) { - if (window == NULL) - return; - - // delete semaphore when set to invalid - switch (sem) { - case B_BAD_SEM_ID: - case B_NO_MORE_SEMS: - case -1: - if (window->fMenuSem > 0) - delete_sem(window->fMenuSem); - break; - - default: - break; - } - - window->fMenuSem = sem; + if (window != NULL) + window->fMenuSem = sem; }