1 /* 2 * Copyright (c) 2007-2014, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Author: 6 * Łukasz 'Sil2100' Zemczak <sil2100@vexillium.org> 7 * Stephan Aßmus <superstippi@gmx.de> 8 */ 9 10 11 #include "PackageImageViewer.h" 12 13 14 BlockingWindow::BlockingWindow(BRect frame, const char* title, uint32 flags) 15 : 16 BWindow(frame, title, B_MODAL_WINDOW, 17 B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_NOT_CLOSABLE | flags), 18 fSemaphore(-1), 19 fReturnValue(0) 20 { 21 } 22 23 24 BlockingWindow::~BlockingWindow() 25 { 26 } 27 28 29 bool 30 BlockingWindow::QuitRequested() 31 { 32 ReleaseSem(0); 33 return true; 34 } 35 36 37 int32 38 BlockingWindow::Go() 39 { 40 int32 returnValue = 0; 41 42 // Since this class can be thought of as a modified BAlert window, no use 43 // to reinvent a well fledged wheel. This concept has been borrowed from 44 // the current BAlert implementation 45 fSemaphore = create_sem(0, "PackageInstaller BlockingWindow"); 46 if (fSemaphore < B_OK) { 47 Quit(); 48 return returnValue; 49 } 50 51 thread_id callingThread = find_thread(NULL); 52 BWindow* window = dynamic_cast<BWindow*>(BLooper::LooperForThread( 53 callingThread)); 54 Show(); 55 56 if (window != NULL) { 57 // Make sure calling window thread, which is blocked here, is updating 58 // the window from time to time. 59 status_t ret; 60 for (;;) { 61 do { 62 ret = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, 50000); 63 } while (ret == B_INTERRUPTED); 64 65 if (ret == B_BAD_SEM_ID) 66 break; 67 window->UpdateIfNeeded(); 68 } 69 } else { 70 // Since there are no spinlocks, wait until the semaphore is free 71 while (acquire_sem(fSemaphore) == B_INTERRUPTED) { 72 } 73 } 74 75 returnValue = fReturnValue; 76 77 if (Lock()) 78 Quit(); 79 80 return returnValue; 81 } 82 83 84 void 85 BlockingWindow::ReleaseSem(int32 returnValue) 86 { 87 if (fSemaphore >= B_OK) { 88 delete_sem(fSemaphore); 89 fSemaphore = -1; 90 fReturnValue = returnValue; 91 } 92 } 93