-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bad9759
commit 8d16360
Showing
2 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "tpromise.h" | ||
|
||
|
||
void * | ||
AwaitTPromise( | ||
TPromise *promise | ||
) | ||
{ | ||
pthread_mutex_lock(&promise->mutex); | ||
while(!promise->resolved) | ||
{ pthread_cond_wait(&promise->cond, &promise->mutex); | ||
} | ||
pthread_mutex_unlock(&promise->mutex); | ||
return promise->data; | ||
} | ||
|
||
void | ||
DestroyTPromise( | ||
TPromise *promise | ||
) | ||
{ | ||
if(!promise) | ||
{ return; | ||
} | ||
|
||
pthread_mutex_destroy(&promise->mutex); | ||
pthread_cond_destroy(&promise->cond); | ||
|
||
free(promise); | ||
} | ||
|
||
int | ||
IsTPromiseDone( | ||
TPromise *promise | ||
) | ||
{ | ||
int promise_done = 0; | ||
|
||
if(!promise) | ||
{ return promise_done; | ||
} | ||
|
||
pthread_mutex_lock(&promise->mutex); | ||
if(promise->resolved) | ||
{ promise_done = 1; | ||
} | ||
pthread_mutex_unlock(&promise->mutex); | ||
|
||
return promise_done; | ||
} | ||
|
||
TPromise * | ||
NewTPromise( | ||
void | ||
) | ||
{ | ||
TPromise *promise = malloc(sizeof(*promise)); | ||
if(promise) | ||
{ | ||
int status = NewTPromiseFilled(promise); | ||
if(status != EXIT_SUCCESS) | ||
{ | ||
free(promise); | ||
promise = NULL; | ||
} | ||
} | ||
return promise; | ||
} | ||
|
||
int | ||
NewTPromiseFilled( | ||
TPromise *promise_return | ||
) | ||
{ | ||
if(!promise_return) | ||
{ return EXIT_FAILURE; | ||
} | ||
const TPromise _cpy = | ||
{ | ||
.data = NULL, | ||
.resolved = 0, | ||
.mutex = PTHREAD_MUTEX_INITIALIZER, | ||
.cond = PTHREAD_COND_INITIALIZER, | ||
}; | ||
*promise_return = _cpy; | ||
return EXIT_SUCCESS; | ||
} | ||
|
||
void | ||
ResolveTPromise( | ||
TPromise *promise, | ||
void *data | ||
) | ||
{ | ||
pthread_mutex_lock(&promise->mutex); | ||
if(!promise->resolved) | ||
{ | ||
promise->data = data; | ||
promise->resolved = 1; | ||
} | ||
pthread_cond_signal(&promise->cond); | ||
pthread_mutex_unlock(&promise->mutex); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
#ifndef __THREAD__PROMISE__H__ | ||
#define __THREAD__PROMISE__H__ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#include <pthread.h> | ||
|
||
typedef struct TPromise TPromise; | ||
|
||
struct | ||
TPromise | ||
{ | ||
void *data; | ||
int resolved; | ||
/* 4bytes pad */ | ||
|
||
pthread_mutex_t mutex; | ||
pthread_cond_t cond; | ||
}; | ||
|
||
/* (A)Waits for a promise to resolve. | ||
* | ||
* NOTE: NULL may be returned if ResolveTPromise() was specified as NULL data. | ||
* NOTE: Awaiting a promise multiple times will not yield different results. | ||
* NOTE: Attempting to await a destroyed promise is undefined. | ||
* | ||
* RETURN: Data from Promise. | ||
*/ | ||
void * | ||
AwaitTPromise( | ||
TPromise *promise | ||
); | ||
|
||
|
||
/* Destroys the given promise, usage of promise after being destroyed is undefined. | ||
* | ||
* NOTE: if a promise is being resolved or awaited, behaviour is undefined. | ||
* | ||
*/ | ||
void | ||
DestroyTPromise( | ||
TPromise *promise | ||
); | ||
|
||
/* Returns wheter or not promise has resolved its data. | ||
* | ||
* RETURN: true on is Done. | ||
* RETURN: false otherwise. | ||
*/ | ||
int | ||
IsTPromiseDone( | ||
TPromise *promise | ||
); | ||
|
||
/* Allocates and intializes a promise for use. | ||
* | ||
* NOTE: This is the only Failure point for TPromises. | ||
* | ||
* RETURN: TPromise * on Success. | ||
* RETURN: NULL on Failure. | ||
*/ | ||
TPromise * | ||
NewTPromise( | ||
void | ||
); | ||
|
||
/* Intializes a promise for use. | ||
* | ||
* NOTE: This is the only Failure point for TPromises. | ||
* NOTE: field 'promise_return' SHOULD be allocated memory, at the minimum static stack memory. | ||
* This is to avoid deadlocks in threads. | ||
* | ||
* RETURN: EXIT_SUCCESS on Success. | ||
* RETURN: EXIT_FAILURE on Failure. | ||
*/ | ||
int | ||
NewTPromiseFilled( | ||
TPromise *promise_return | ||
); | ||
|
||
/* Resolves a TPromise by updating its data. | ||
* | ||
* NOTE: field 'data' MAY be NULL, in such cases NULL will be set as data. | ||
* NOTE: A promise may only be resolved once, further attempts to resolve a promise, | ||
* Will simply 'wakeup' the other process/thread awaiting for the response. | ||
* NOTE: Attempting to resolve a destroyed promise is undefined. | ||
*/ | ||
void | ||
ResolveTPromise( | ||
TPromise *promise, | ||
void *data | ||
); | ||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |