Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions Sources/Objectively/Operation.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static void addDependency(Operation *self, Operation *dependency) {
*/
static void cancel(Operation *self) {

if (__atomic_load_n(&self->isCancelled, __ATOMIC_ACQUIRE) || self->isFinished) {
if ($(self, isCancelled) || self->isFinished) {
return;
}

Expand Down Expand Up @@ -133,6 +133,14 @@ static Operation *initWithFunction(Operation *self, OperationFunction function,
return self;
}

/**
* @fn bool Operation::isCancelled(const Operation *self)
* @memberof Operation
*/
static bool isCancelled(const Operation *self) {
return __atomic_load_n(&self->isCancelled, __ATOMIC_ACQUIRE);
}
Comment on lines +140 to +142

/**
* @fn bool Operation::isReady(const Operation *self)
* @memberof Operation
Expand All @@ -143,7 +151,7 @@ static bool isReady(const Operation *self) {
return false;
}

if (__atomic_load_n(&self->isCancelled, __ATOMIC_ACQUIRE)) {
if ($(self, isCancelled)) {
return true;
}

Expand Down Expand Up @@ -180,7 +188,7 @@ static void start(Operation *self) {
return;
}

if (__atomic_load_n(&self->isCancelled, __ATOMIC_ACQUIRE) == false) {
if ($(self, isCancelled) == false) {
self->isExecuting = true;
self->function(self);
self->isExecuting = false;
Expand Down Expand Up @@ -221,6 +229,7 @@ static void initialize(Class *clazz) {
((OperationInterface *) clazz->interface)->dependencies = dependencies;
((OperationInterface *) clazz->interface)->init = init;
((OperationInterface *) clazz->interface)->initWithFunction = initWithFunction;
((OperationInterface *) clazz->interface)->isCancelled = isCancelled;
((OperationInterface *) clazz->interface)->isReady = isReady;
((OperationInterface *) clazz->interface)->removeDependency = removeDepdenency;
((OperationInterface *) clazz->interface)->start = start;
Expand Down
15 changes: 13 additions & 2 deletions Sources/Objectively/Operation.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ struct Operation {

/**
* @brief `true` when this Operation has been cancelled, `false` otherwise.
* @remarks Operation::cancel MAY set this from another thread while the Operation executes, so
* the function SHOULD read it with `__atomic_load_n(&operation->isCancelled, __ATOMIC_ACQUIRE)`.
* @remarks Operation::cancel MAY set this from another thread while the Operation executes.
* Read it with Operation::isCancelled.
* @private
*/
bool isCancelled;

Expand Down Expand Up @@ -182,6 +183,16 @@ struct OperationInterface {
*/
Operation *(*initWithFunction)(Operation *self, OperationFunction function, ident data);

/**
* @fn bool Operation::isCancelled(const Operation *self)
* @param self The Operation.
* @return `true` if this Operation has been cancelled, `false` otherwise.
* @remarks This MAY be called from any thread, including from the Operation's function while
* another thread cancels it.
* @memberof Operation
*/
bool (*isCancelled)(const Operation *self);

/**
* @fn bool Operation::isReady(const Operation *self)
* @param self The Operation.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Objectively/OperationQueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static void dealloc(Object *self) {
static void addOperation(OperationQueue *self, Operation *operation) {

assert(operation);
assert(operation->isCancelled == false);
assert($(operation, isCancelled) == false);
assert(operation->isExecuting == false);
assert(operation->isFinished == false);

Expand Down
9 changes: 9 additions & 0 deletions Sources/Objectively/Thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ static Thread *initWithFunction(Thread *self, ThreadFunction function, ident dat
return self;
}

/**
* @fn bool Thread::isCancelled(const Thread *self)
* @memberof Thread
*/
static bool isCancelled(const Thread *self) {
return __atomic_load_n(&self->isCancelled, __ATOMIC_ACQUIRE);
}

/**
* @fn void Thread::join(Thread *self, ident *status)
* @memberof Thread
Expand Down Expand Up @@ -194,6 +202,7 @@ static void initialize(Class *clazz) {
((ThreadInterface *) clazz->interface)->detach = detach;
((ThreadInterface *) clazz->interface)->init = init;
((ThreadInterface *) clazz->interface)->initWithFunction = initWithFunction;
((ThreadInterface *) clazz->interface)->isCancelled = isCancelled;
((ThreadInterface *) clazz->interface)->join = join;
((ThreadInterface *) clazz->interface)->kill = _kill;
((ThreadInterface *) clazz->interface)->start = start;
Expand Down
13 changes: 11 additions & 2 deletions Sources/Objectively/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ struct Thread {

/**
* @brief `true` when this Thread has been cancelled, `false` otherwise.
* @remarks Thread::cancel sets this from another thread, so the ThreadFunction SHOULD read it
* with `__atomic_load_n(&thread->isCancelled, __ATOMIC_ACQUIRE)`.
* @remarks Thread::cancel sets this from another thread. Read it with Thread::isCancelled.
* @private
*/
bool isCancelled;

Expand Down Expand Up @@ -157,6 +157,15 @@ struct ThreadInterface {
*/
Thread *(*initWithFunction)(Thread *self, ThreadFunction function, ident data);

/**
* @fn bool Thread::isCancelled(const Thread *self)
* @param self The Thread.
* @return `true` if this Thread has been cancelled, `false` otherwise.
* @remarks This MAY be called from any thread, including while another thread cancels this one.
* @memberof Thread
*/
bool (*isCancelled)(const Thread *self);

/**
* @fn void Thread::join(Thread *self, ident *status)
* @brief Wait for the specified Thread to terminate.
Expand Down
2 changes: 1 addition & 1 deletion Sources/Objectively/ThreadPool.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ static ident run(Thread *thread) {

while (true) {

while (self->head == NULL && thread->isCancelled == false) {
while (self->head == NULL && $(thread, isCancelled) == false) {
$(condition, wait);
}

Expand Down
12 changes: 6 additions & 6 deletions Sources/Objectively/URLSession.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static ident taskWithRequest(URLSession *self, ident task, URLRequest *request,
bool isInvalidated;

synchronized(self->condition, {
isInvalidated = self->thread->isCancelled;
isInvalidated = $(self->thread, isCancelled);
if (isInvalidated == false) {
$(self->tasks, addObject, task);
$(self->condition, signal);
Expand Down Expand Up @@ -91,7 +91,7 @@ static URLSessionDataTask *dataTaskWithRequest(URLSession *self, URLRequest *req
bool isInvalidated;

synchronized(self->condition, {
isInvalidated = self->thread->isCancelled;
isInvalidated = $(self->thread, isCancelled);
});

if (isInvalidated) {
Expand All @@ -107,7 +107,7 @@ static URLSessionDataTask *dataTaskWithRequest(URLSession *self, URLRequest *req
}

synchronized(self->condition, {
isInvalidated = self->thread->isCancelled;
isInvalidated = $(self->thread, isCancelled);
if (isInvalidated == false) {
$(self->tasks, addObject, task);
$(self->condition, signal);
Expand Down Expand Up @@ -212,10 +212,10 @@ static ident run(Thread *thread) {

bool idle;
synchronized(self->condition, {
while (!hasWork(self) && !(thread->isCancelled && self->tasks->count == 0)) {
while (!hasWork(self) && !($(thread, isCancelled) && self->tasks->count == 0)) {
$(self->condition, wait);
}
idle = thread->isCancelled && self->tasks->count == 0;
idle = $(thread, isCancelled) && self->tasks->count == 0;
});

if (idle) {
Expand Down Expand Up @@ -392,7 +392,7 @@ static void invalidateAndCancel(URLSession *self) {
bool isInvalidated;

synchronized(self->condition, {
isInvalidated = self->thread->isCancelled;
isInvalidated = $(self->thread, isCancelled);
if (isInvalidated == false) {
$(self->thread, cancel);
$(self->condition, signal);
Expand Down
16 changes: 16 additions & 0 deletions Tests/Objectively/Thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,27 @@ START_TEST(cond) {

} END_TEST

START_TEST(isCancelled) {

Thread *thread = $(alloc(Thread), initWithFunction, increment, NULL);
ck_assert(thread != NULL);

ck_assert($(thread, isCancelled) == false);

$(thread, cancel);

ck_assert($(thread, isCancelled));

release(thread);

} END_TEST

int main(int argc, char **argv) {

TCase *tcase = tcase_create("Thread");
tcase_add_test(tcase, thread);
tcase_add_test(tcase, cond);
tcase_add_test(tcase, isCancelled);

Suite *suite = suite_create("Thread");
suite_add_tcase(suite, tcase);
Expand Down
4 changes: 2 additions & 2 deletions Tests/Objectively/ThreadPool.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static ident waitForGateOrCancel(Thread *thread) {
$(condition, broadcast);
});

while (__atomic_load_n(&thread->isCancelled, __ATOMIC_ACQUIRE) == false) {
while ($(thread, isCancelled) == false) {
usleep(1000);
}

Expand Down Expand Up @@ -281,7 +281,7 @@ static ident untilCancelled(Thread *thread) {
$(condition, broadcast);
});

while (__atomic_load_n(&thread->isCancelled, __ATOMIC_ACQUIRE) == false) {
while ($(thread, isCancelled) == false) {
usleep(1000);
}

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
AC_PREREQ(2.69)

AC_INIT([Objectively], [2.3.0], [jay@jaydolan.com])
AC_INIT([Objectively], [2.4.0], [jay@jaydolan.com])

AC_CONFIG_HEADERS([Sources/Objectively/Config.h])
AC_CONFIG_MACRO_DIR([m4])
Expand Down
Loading