diff --git a/src/servers/media/Jamfile b/src/servers/media/Jamfile index a9d273657c..b9b571d91d 100644 --- a/src/servers/media/Jamfile +++ b/src/servers/media/Jamfile @@ -7,5 +7,6 @@ Server media_server : AppManager.cpp BufferManager.cpp NodeManager.cpp + Queue.cpp ; LinkSharedOSLibs media_server : be libmedia.so root ; diff --git a/src/servers/media/Queue.cpp b/src/servers/media/Queue.cpp new file mode 100644 index 0000000000..93ed5f48ef --- /dev/null +++ b/src/servers/media/Queue.cpp @@ -0,0 +1,91 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ +/* This is a simple multi thread save queue. + * + * One thread calls AddItem() to add items, and when it + * is finished doing so, it calls Terminate(). Another + * thread calls RemoveItem() to remove items from the + * queue. RemoveItem() blocks when no items are available. + * As soon as Terminate() is called and the queue is empty, + * RemoveItem() returns NULL. + */ + +#include +#include +#include + +#include "Queue.h" + +Queue::Queue() + : fList(new BList), + fLocker(new BLocker), + fSem(create_sem(0,"queue sem")) +{ +} + +Queue::~Queue() +{ + if (fSem > 0) + delete_sem(fSem); + delete fLocker; + delete fList; +} + +status_t +Queue::Terminate() +{ + status_t rv; + + fLocker->Lock(); + if (fSem < 0) { + rv = B_ERROR; + } else { + delete_sem(fSem); + fSem = -1; + rv = B_OK; + } + fLocker->Unlock(); + return rv; +} + +status_t +Queue::AddItem(void *item) +{ + status_t rv; + + fLocker->Lock(); + if (fSem < 0) { + rv = B_ERROR; + } else { + if (B_OK == fList->AddItem(item)) { + release_sem(fSem); + rv = B_OK; + } else { + rv = B_ERROR; + } + } + fLocker->Unlock(); + return rv; +} + +void * +Queue::RemoveItem() +{ + status_t rv; + void *item; + + // if the semaphore is deleted by Terminate(), + // this will no longer block + while (acquire_sem(fSem) == B_INTERRUPTED) + ; + + // if the list is empty, which can only happen after + // Terminate() was called, item will be NULL + fLocker->Lock(); + item = fList->RemoveItem((int32)0); + fLocker->Unlock(); + + return item; +} diff --git a/src/servers/media/Queue.h b/src/servers/media/Queue.h new file mode 100644 index 0000000000..ac717f2226 --- /dev/null +++ b/src/servers/media/Queue.h @@ -0,0 +1,21 @@ +/* + * Copyright 2002, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +class Queue +{ +public: + Queue(); + ~Queue(); + + status_t Terminate(); + + status_t AddItem(void *item); + void * RemoveItem(); + +private: + BList *fList; + BLocker *fLocker; + sem_id fSem; +};