18 #include <semaphore.h> 45 InitializeCriticalSection (&cs);
47 pthread_mutex_init (&mutex, NULL);
57 CriticalSectionEnd ();
59 pthread_mutex_destroy (&mutex);
89 return (blocked && (curThreadId != blockerThreadId));
97 EnterCriticalSection (&cs);
99 pthread_mutex_lock (&mutex);
109 LeaveCriticalSection (&cs);
111 pthread_mutex_unlock (&mutex);
121 if (blocked && (curThreadId == blockerThreadId))
127 CriticalSectionStart ();
129 blockerThreadId = curThreadId;
143 throw KKB::
KKException ("GoalKeeperSimple::EndBlock Name[" + name
+ "] Is not currently blocked.");
145 if (curThreadId != blockerThreadId)
146 throw KKB::
KKException ("GoalKeeperSimple::EndBlock Name[" + name
+ "] ThreadId[" + blockerThreadId
+ "] Currently holds Block; our ThreadId[" + curThreadId
+ "]");
152 blockerThreadId = -1;
153 CriticalSectionEnd ();
165 HANDLE mutexCreateHandle = CreateMutex (NULL,
169 if (!mutexCreateHandle)
171 KKStr errMsg =
"GoalKeeperSimple::Create ***ERROR*** CreateMutex failed; returned back NULL; _name:" + _name;
172 cerr << endl << errMsg << endl << endl;
173 throw KKException (errMsg);
176 WaitForSingleObject (mutexCreateHandle, INFINITE);
178 if (_newGoalKeeper == NULL)
181 if (existingGoalKeepers == NULL)
184 atexit (GoalKeeperSimple::FinalCleanUp);
186 existingGoalKeepers->PushOnBack (_newGoalKeeper);
189 ReleaseMutex (mutexCreateHandle);
190 CloseHandle(mutexCreateHandle);
192 sem_t* semHandle = sem_open (
"GoalKeeperClass", O_CREAT, 0644, 1);
193 if (semHandle == SEM_FAILED)
196 <<
"GoalKeeperSimple::Create Error[" << errno <<
"] opening '/GoalKeeperSimple' Semaphore." << std::endl
199 perror(
"GoalKeeperSimple::Create Error Opening Semaphore 'GoalKeeperSimple'");
201 throw "GoalKeeperSimple::Create Error opening 'GoalKeeperSimple'.";
204 sem_wait (semHandle);
206 if (_newGoalKeeper == NULL)
208 _newGoalKeeper =
new GoalKeeperSimple (_name);
209 if (existingGoalKeepers == NULL)
211 existingGoalKeepers =
new GoalKeeperSimpleList (
true);
212 atexit (GoalKeeperSimple::FinalCleanUp);
214 existingGoalKeepers->PushOnBack (_newGoalKeeper);
217 sem_post (semHandle);
218 sem_close (semHandle);
233 bool& _didNotExistYet
237 HANDLE mutexCreateHandle = CreateMutex (NULL,
241 if (!mutexCreateHandle)
243 KKStr errMsg =
"GoalKeeperSimple::CreateAndStartBlock ***ERROR*** CreateMutex failed; returned back NULL; _name:" + _name;
244 cerr << endl << errMsg << endl << endl;
245 throw KKException(errMsg);
248 WaitForSingleObject (mutexCreateHandle, INFINITE);
250 if (_newGoalKeeper == NULL)
252 _didNotExistYet =
true;
255 if (existingGoalKeepers == NULL)
258 atexit (GoalKeeperSimple::FinalCleanUp);
260 existingGoalKeepers->PushOnBack (_newGoalKeeper);
264 _didNotExistYet =
false;
269 ReleaseMutex (mutexCreateHandle);
270 CloseHandle(mutexCreateHandle);
272 sem_t* semHandle = sem_open (
"GoalKeeperClass", O_CREAT, 0644, 1);
273 if (semHandle == SEM_FAILED)
276 <<
"GoalKeeperSimple::Create Error[" << errno <<
"] opening '/GoalKeeperSimple' Semaphore." << std::endl
279 perror(
"GoalKeeperSimple::Create Error Opening Semaphore 'GoalKeeperSimple'");
281 throw "GoalKeeperSimple::Create Error opening 'GoalKeeperSimple'.";
284 sem_wait (semHandle);
286 if (_newGoalKeeper == NULL)
288 _didNotExistYet =
true;
289 _newGoalKeeper =
new GoalKeeperSimple (_name);
290 if (existingGoalKeepers == NULL)
292 existingGoalKeepers =
new GoalKeeperSimpleList (
true);
293 atexit (GoalKeeperSimple::FinalCleanUp);
295 existingGoalKeepers->PushOnBack (_newGoalKeeper);
299 _didNotExistYet =
false;
302 _newGoalKeeper->StartBlock ();
304 sem_post (semHandle);
305 sem_close (semHandle);
316 HANDLE mutexCreateHandle = CreateMutex (NULL,
320 if (!mutexCreateHandle)
322 KKStr errMsg =
"GoalKeeperSimple::Destroy ***ERROR*** CreateMutex failed; returned back NULL";
323 cerr << endl << errMsg << endl << endl;
324 throw KKException(errMsg);
327 WaitForSingleObject (mutexCreateHandle, INFINITE);
329 if (_goalKeeperInstance == NULL)
335 kkint32 existingInstanceIdx = existingGoalKeepers->PtrToIdx (_goalKeeperInstance);
336 if (existingInstanceIdx < 0)
342 existingGoalKeepers->DeleteEntry (_goalKeeperInstance);
343 delete _goalKeeperInstance;
344 _goalKeeperInstance = NULL;
348 ReleaseMutex (mutexCreateHandle);
349 CloseHandle(mutexCreateHandle);
351 sem_t* semHandle = sem_open (
"GoalKeeperClass", O_CREAT, 0644, 1);
352 if (semHandle == SEM_FAILED)
355 <<
"GoalKeeperSimple::Create Error[" << errno <<
"] opening '/GoalKeeperSimple' Semaphore." << std::endl
358 perror(
"GoalKeeperSimple::Create Error Opening Semaphore 'GoalKeeperSimple'");
360 throw "GoalKeeperSimple::Create Error opening 'GoalKeeperSimple'.";
363 sem_wait (semHandle);
365 if (_goalKeeperInstance == NULL)
371 kkint32 existingInstanceIdx = existingGoalKeepers->PtrToIdx (_goalKeeperInstance);
372 if (existingInstanceIdx >= 0)
378 existingGoalKeepers->DeleteEntry (_goalKeeperInstance);
379 delete _goalKeeperInstance;
380 _goalKeeperInstance = NULL;
384 sem_post (semHandle);
385 sem_close (semHandle);
394 if (existingGoalKeepers)
396 delete existingGoalKeepers;
397 existingGoalKeepers = NULL;
bool BlockedByAnotherThread()
Returns true if a different thread has this instance of "GoalKeeperSimple" locked.
GoalKeeperSimpleList * GoalKeeperSimpleListPtr
kkint32 MemoryConsumedEstimated() const
KKStr operator+(kkint32 right) const
static void Destroy(volatile GoalKeeperSimplePtr &_goalKeeperInstance)
Destroys an existing instance of GoalKeeperSimple.
kkint32 BlockerThreadId()
ThreadId of thread that currently holds the Block -1 indicates no Block.
A simple/ light-weight implementation of critical section blocking.
KKStr operator+(const char *right) const
void EndBlock()
Ends the block and allows other threads to pass through StatBlock.
GoalKeeperSimpleList(bool _owner)
KKStr operator+(const char *left, const KKStr &right)
KKStr(const KKStr &str)
Copy Constructor.
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of 'std::string' strings.
static void CreateAndStartBlock(const KKStr &_name, volatile GoalKeeperSimplePtr &_newGoalKeeper, bool &_didNotExistYet)
Create a GoalKeeperSimple object and avoid a race condition doing it.
static void Create(const KKStr &_name, volatile GoalKeeperSimplePtr &_newGoalKeeper)
Create a GoalKeeperSimple object and avoid a race condition doing it.
void StartBlock()
Initiates a Block as long as another thread has not already locked this object.
static void FinalCleanUp()
Will be registered with 'atexit' so that it will be called when program is unloaded from memory...
bool Blocked()
Will return true if any thread lock on this instance of "GoalKeeperSimple".
GoalKeeperSimple * GoalKeeperSimplePtr
KKException(const KKStr &_exceptionStr)
kkint32 MemoryConsumedEstimated() const