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