#include <ts/ts.h>

int TSContCall(TSCont contp, TSEvent event, void * edata)


Call the continuation contp as if from a hook with the event type event and data of edata. Presuming contp was created in a manner like:

TSContCreate(CallbackHandler, TSMutexCreate());

Therefore there is a function:

int CallbackHandler(TSCont this, TSEvent id, void * data);

As a result TSContCall() will effectively do:

return CallbackHandler(contp, event, edata);

If there is a mutex associated with contp, TSContCall() assumes that mutex is held already. TSContCall() will directly call the handler associated with the continuation. It will return the value returned by the handler in contp.

If contp has a mutex, the plugin must acquire the lock on the mutex for contp before calling TSContCall(). See TSContMutexGet() and TSMutexLockTry() for mechanisms for doing this.

The most common case is the code called by TSContCall() must complete before further code is executed at the call site. An alternative approach to handling the locking directly would be to split the call site into two continuations, one of which is signalled (possibly via TSContCall()) from the original TSContCall() target.

Note mutexes returned by TSMutexCreate() are recursive mutexes, therefore if the lock is already held on the thread of execution acquiring the lock again is very fast. Mutexes are also shareable so that the same mutex can be used for multiple continuations.:

TSMutex mutex = TSMutexCreate();
TSCont cont1 = TSContCreate(Handler1, mutex);
TSCont cont2 = TSContCreate(Handler2, mutex);

In this example case, cont1 can assume the lock for cont2 is held. This should be considered carefully because for the same reason any thread protection between the continuations is removed. This works well for tightly coupled continuations that always operate in a fixed sequence.