xref: /haiku/src/apps/packageinstaller/BlockingWindow.cpp (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
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