Skip to content

Instantly share code, notes, and snippets.

@glaudiston
Last active September 16, 2016 21:50
Show Gist options
  • Save glaudiston/315108722c6526b41f52574ace762cb5 to your computer and use it in GitHub Desktop.
Save glaudiston/315108722c6526b41f52574ace762cb5 to your computer and use it in GitHub Desktop.
C Promises
// ref https://computing.llnl.gov/tutorials/pthreads/#WhyPthreads
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int promises=0;
typedef void *( FunctionPointerNoArgs )();
typedef void *( *FunctionPointer )( void * );
typedef void *( *PromiseBaseFunctionPointer )( FunctionPointerNoArgs *, FunctionPointerNoArgs * );
typedef struct Promise{
enum { PromiseStatePending, PromiseStateFulfilled, PromiseStateRejected } state;
FunctionPointer then;
FunctionPointer catch;
FunctionPointer whatever;
void * lastResult;
} Promise;
void * PromiseThreadFunction()
{
//functionBase(resolve, reject);
//resolveTest()
}
Promise * newPromise(PromiseBaseFunctionPointer functionBase)
{
Promise * retval=(Promise*) malloc( sizeof(Promise) );
retval->state=PromiseStatePending;
FunctionPointer * promiseThenArray = malloc(sizeof(FunctionPointer));
int promiseThenArrayLength=0;
void * lastResult;
void * setPromiseThen(FunctionPointer thenCallBack)
{
printf("DBG: then value seted for promise\n"); fflush(stdout);
promiseThenArray=realloc(promiseThenArray, sizeof(FunctionPointer) * ++promiseThenArrayLength);
promiseThenArray[promiseThenArrayLength-1]=thenCallBack;
if ( retval->state != PromiseStatePending ){
thenCallBack(retval->lastResult);
}
return retval;
}
int promiseCatchArrayLength=0;
FunctionPointer * promiseCatchArray;
void * setPromiseCatch(FunctionPointer catchCallBack)
{
printf("DBG: catch value seted for promise\n"); fflush(stdout);
return retval;
}
void * setPromiseFinally()
{
printf("DBG: whatever value seted for promise\n"); fflush(stdout);
return retval;
}
retval->then=(FunctionPointer)setPromiseThen;
retval->catch=(FunctionPointer)setPromiseCatch;
retval->whatever=setPromiseFinally;
void * whatever(void * result)
{
printf("DBG: whatever value call\n"); fflush(stdout);
}
void * resolve(void * result)
{
retval->state=PromiseStateFulfilled;
printf("intern resolve fn called\n"); fflush(stdout);
retval->lastResult=result;
int i;
for ( i=0; i<promiseThenArrayLength; i++ ){
retval->lastResult=promiseThenArray[i](retval->lastResult);
}
whatever(retval->lastResult);
};
void * reject(void * result)
{
retval->state=PromiseStateRejected;
printf("inter reject fn arg called\n");
retval->lastResult=result;
int i;
for ( i=0; i<promiseCatchArrayLength; i++){
retval->lastResult=promiseCatchArray[i](retval->lastResult);
}
whatever(retval->lastResult);
}
retval->then=(FunctionPointer)setPromiseThen;
// call it in a new thread
functionBase(resolve, reject);
//PromiseThreadFunction(retval);
return retval;
}
void promiseTest()
{
void * functionBaseTest(FunctionPointer resolve, FunctionPointer reject)
{
printf("runing the base test function...\n");
resolve("resolve true value\n");
}
void * fnThenTest()
{
printf("Promise resolved, fnThenTest called\nWELL DONE !\n");
}
Promise * p = newPromise(functionBaseTest);
p->then(fnThenTest);
}
int main(int argc, char * argv[])
{
promiseTest();
/*
rc = pthread_join(thread[0], &status);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
*/
// end the main thread
pthread_exit(NULL);
return 0;
}
// ref https://computing.llnl.gov/tutorials/pthreads/#WhyPthreads
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int promises=0;
struct Promise;
// typedef void *( FunctionPointerNoArgs )();
typedef void *( *PromiseCallBackFunctionPointer )( struct Promise *, void * );
typedef struct Promise *( *PromiseFunctionPointer )( struct Promise *, void * );
typedef void ( *PromiseBaseFunctionPointer )( struct Promise *, PromiseCallBackFunctionPointer, PromiseCallBackFunctionPointer );
typedef struct Promise{
enum { PromiseStatePending, PromiseStateFulfilled, PromiseStateRejected } state;
PromiseFunctionPointer then;
PromiseFunctionPointer catch;
PromiseFunctionPointer whatever;
void * lastResult;
// internal items
int _promiseThenArrayLength;
PromiseCallBackFunctionPointer * _promiseThenArray;
int _promiseCatchArrayLength;
PromiseCallBackFunctionPointer * _promiseCatchArray;
int _promiseWhateverArrayLength;
PromiseCallBackFunctionPointer * _promiseWhateverArray;
} Promise;
/*
void * PromiseThreadFunction()
{
//functionBase(resolve, reject);
//resolveTest()
}
*/
// store all promises here to avoid lost reference
struct Promises;
Promise setPromiseThen(Promise *p, PromiseCallBackFunctionPointer thenCallBack)
{
printf("DBG: in then promise is in %p\n",p);
printf("DBG: then value seted for promise\n"); fflush(stdout);
// printf("DBG: size %i..\n", sizeof(FunctionPointer)); fflush(stdout);
p->_promiseThenArray=realloc(p->_promiseThenArray, sizeof(PromiseCallBackFunctionPointer) * ++(p->_promiseThenArrayLength));
printf("DBG: realocated, set...%i\n", (p->_promiseThenArrayLength)); fflush(stdout);
p->_promiseThenArray[(p->_promiseThenArrayLength)-1]=thenCallBack;
if ( p->state != PromiseStatePending ){
printf("DBG: lets call it\n"); fflush(stdout);
thenCallBack(p, p->lastResult);
}
//printf("DBG: return p %i\n", (int)p);fflush(stdout);
return *p;
}
Promise setPromiseCatch(Promise *p, PromiseCallBackFunctionPointer catchCallBack)
{
printf("DBG: catch value seted for promise\n"); fflush(stdout);
return *p;
}
Promise setPromiseWhatever(Promise *p, PromiseCallBackFunctionPointer whateverCallBack)
{
printf("DBG: whatever value seted for promise\n"); fflush(stdout);
return *p;
}
void * whatever(void * result)
{
printf("DBG: whatever value call\n"); fflush(stdout);
return result;
}
void * resolve(Promise *p, void * result)
{
p->state=PromiseStateFulfilled;
printf("DBG: intern resolve fn called\n"); fflush(stdout);
p->lastResult=result;
int i;
for ( i=0; i< (p->_promiseThenArrayLength); i++ ){
p->lastResult=p->_promiseThenArray[i](p, p->lastResult);
}
whatever(p->lastResult);
return p->lastResult;
};
void * reject(Promise *p, void * result)
{
p->state=PromiseStateRejected;
printf("DBG: inter reject fn arg called\n");
p->lastResult=result;
int i;
for ( i=0; i<p->_promiseCatchArrayLength; i++){
p->lastResult=p->_promiseCatchArray[i](p, p->lastResult);
}
whatever(p->lastResult);
return p->lastResult;
}
Promise * newPromise(PromiseBaseFunctionPointer functionBase)
{
Promise * retval=(Promise*) malloc( sizeof(Promise) );
retval->state=PromiseStatePending;
retval->_promiseThenArray = malloc(sizeof(PromiseCallBackFunctionPointer));
retval->_promiseThenArrayLength=0;
printf("DBG: in newPromise promise is in %p\n",retval);
void * lastResult;
int promiseCatchArrayLength=0;
PromiseFunctionPointer * promiseCatchArray;
retval->then=(PromiseFunctionPointer)setPromiseThen;
retval->catch=(PromiseFunctionPointer)setPromiseCatch;
retval->whatever=(PromiseFunctionPointer)setPromiseWhatever;
// call it in a new thread
functionBase(retval, resolve, reject);
//PromiseThreadFunction(retval);
return retval;
}
void functionBaseTest(Promise *p, PromiseCallBackFunctionPointer resolve, PromiseCallBackFunctionPointer reject)
{
printf("DBG: running the base test function...\n");
resolve(p, "WELL DONE!!!\n");
}
void * fnThenTest(void * result)
{
printf("DBG: Promise resolved, fnThenTest result.\n\nPROMISE RESULT: [%s]\n", (char *) result);
return result;
}
void promiseTest()
{
Promise * p = newPromise(functionBaseTest);
printf("DBG: in promiseTest promise is allocated in %p\n", p);
p->then(p,fnThenTest)->then(p,fnThenTest);
}
int main(int argc, char * argv[])
{
promiseTest();
/*
rc = pthread_join(thread[0], &status);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
*/
// end the main thread
pthread_exit(NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment