#ifndef _H_DISPATCH
#define _H_DISPATCH
#include <dispatch/dispatch.h>
#include <security_utilities/utilities.h>
#include <security_utilities/threading.h>
#include <exception>
namespace Security {
namespace Dispatch {
class ExceptionAwareEnqueuing {
NOCOPY(ExceptionAwareEnqueuing)
public:
ExceptionAwareEnqueuing();
void enqueueWithDispatcher(void (^dispatcher)(dispatch_block_t), dispatch_block_t block);
void throwPendingException();
private:
Mutex mLock;
bool mExceptionPending;
std::exception_ptr mException;
};
class Queue {
NOCOPY(Queue)
public:
Queue(const char *label, bool concurrent, dispatch_qos_class_t qos_class = QOS_CLASS_UNSPECIFIED);
virtual ~Queue();
operator dispatch_queue_t () const { return mQueue; }
void enqueue(dispatch_block_t block);
void wait();
private:
ExceptionAwareEnqueuing enqueuing;
dispatch_queue_t mQueue;
};
class Group {
NOCOPY(Group)
public:
Group();
virtual ~Group();
operator dispatch_group_t () const { return mGroup; }
void enqueue(dispatch_queue_t queue, dispatch_block_t block);
void wait();
private:
ExceptionAwareEnqueuing enqueuing;
dispatch_group_t mGroup;
};
class Semaphore {
NOCOPY(Semaphore)
public:
Semaphore(long count);
Semaphore(Semaphore& semaphore);
virtual ~Semaphore();
operator dispatch_semaphore_t () const { return mSemaphore; };
bool signal();
bool wait(dispatch_time_t timeout = DISPATCH_TIME_FOREVER);
private:
dispatch_semaphore_t mSemaphore;
};
class SemaphoreWait {
NOCOPY(SemaphoreWait)
public:
SemaphoreWait(SemaphoreWait& originalWait);
SemaphoreWait(Semaphore& semaphore, dispatch_time_t timeout = DISPATCH_TIME_FOREVER);
virtual ~SemaphoreWait();
bool acquired() const { return mAcquired; };
private:
Semaphore &mSemaphore;
bool mAcquired;
};
} }
#endif // !_H_DISPATCH