xref: /haiku/src/add-ons/kernel/file_systems/netfs/shared/BlockerPool.cpp (revision 5a1d355fdf2747f80f8c46e2539f844a0b813346)
1 // BlockerPool.cpp
2 
3 #include <new>
4 
5 #include "AutoLocker.h"
6 #include "BlockerPool.h"
7 #include "Vector.h"
8 
9 // BlockerVector
10 struct BlockerPool::BlockerVector : Vector<Blocker> {
11 };
12 
13 // constructor
BlockerPool(int32 count)14 BlockerPool::BlockerPool(int32 count)
15 	: Locker("blocker pool"),
16 	  fFreeBlockersSemaphore(-1),
17 	  fBlockers(NULL),
18 	  fInitStatus(B_NO_INIT)
19 {
20 	fInitStatus = _Init(count);
21 	if (fInitStatus != B_OK)
22 		_Unset();
23 }
24 
25 // destructor
~BlockerPool()26 BlockerPool::~BlockerPool()
27 {
28 	_Unset();
29 }
30 
31 // InitCheck
32 status_t
InitCheck() const33 BlockerPool::InitCheck() const
34 {
35 	return fInitStatus;
36 }
37 
38 // GetBlocker
39 Blocker
GetBlocker()40 BlockerPool::GetBlocker()
41 {
42 	if (fInitStatus != B_OK)
43 		return B_NO_INIT;
44 	status_t error = acquire_sem(fFreeBlockersSemaphore);
45 	if (error != B_OK)
46 		return error;
47 	AutoLocker<BlockerPool> _(this);
48 	if (fInitStatus != B_OK)
49 		return fInitStatus;
50 	Blocker blocker = fBlockers->ElementAt(fBlockers->Count() - 1);
51 	fBlockers->Erase(fBlockers->Count() - 1);
52 	return blocker;
53 }
54 
55 // PutBlocker
56 status_t
PutBlocker(Blocker blocker)57 BlockerPool::PutBlocker(Blocker blocker)
58 {
59 	status_t error = blocker.PrepareForUse();
60 	if (error != B_OK)
61 		return error;
62 	AutoLocker<BlockerPool> _(this);
63 	if (fInitStatus != B_OK)
64 		return fInitStatus;
65 	error = fBlockers->PushBack(blocker);
66 	if (error != B_OK)
67 		return error;
68 	return release_sem(fFreeBlockersSemaphore);
69 }
70 
71 // _Init
72 status_t
_Init(int32 count)73 BlockerPool::_Init(int32 count)
74 {
75 	_Unset();
76 	AutoLocker<BlockerPool> locker(this);
77 	if (!locker.IsLocked())
78 		return B_ERROR;
79 	// create semaphore
80 	fFreeBlockersSemaphore = create_sem(0, "blocker pool free blockers");
81 	if (fFreeBlockersSemaphore < 0)
82 		return fFreeBlockersSemaphore;
83 	// allocate blocker vector
84 	fBlockers = new(std::nothrow) BlockerVector;
85 	if (!fBlockers)
86 		return B_NO_MEMORY;
87 	fInitStatus = B_OK;
88 	// create and add blockers
89 	for (int32 i = 0; i < count; i++) {
90 		Blocker blocker;
91 		status_t error = blocker.InitCheck();
92 		if (error != B_OK)
93 			return error;
94 		error = PutBlocker(blocker);
95 		if (error != B_OK)
96 			return error;
97 	}
98 	return B_OK;
99 }
100 
101 // _Unset
102 void
_Unset()103 BlockerPool::_Unset()
104 {
105 	AutoLocker<BlockerPool> locker(this);
106 	if (fInitStatus == B_OK)
107 		fInitStatus = B_NO_INIT;
108 	delete fBlockers;
109 	fBlockers = NULL;
110 	if (fFreeBlockersSemaphore >= 0)
111 		delete_sem(fFreeBlockersSemaphore);
112 	fFreeBlockersSemaphore = -1;
113 }
114 
115