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
14BlockingWindow::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
24BlockingWindow::~BlockingWindow()
25{
26}
27
28
29bool
30BlockingWindow::QuitRequested()
31{
32	ReleaseSem(0);
33	return true;
34}
35
36
37int32
38BlockingWindow::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
84void
85BlockingWindow::ReleaseSem(int32 returnValue)
86{
87	if (fSemaphore >= B_OK) {
88		delete_sem(fSemaphore);
89		fSemaphore = -1;
90		fReturnValue = returnValue;
91	}
92}
93