Skip to content

Instantly share code, notes, and snippets.

@jsbattig
Created March 5, 2014 23:38
Show Gist options
  • Save jsbattig/9379060 to your computer and use it in GitHub Desktop.
Save jsbattig/9379060 to your computer and use it in GitHub Desktop.
Thread Pooling class headers
/* Copyright 2013 Convey Compliance Systems, Inc.
*
* All rights reserved. No warranty, explicit or implicit, provided.
*/
#ifndef SVCBUS_THREADPOOL_H
#define SVCBUS_THREADPOOL_H
#include <Windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SVCBUS_THREADPOOL_OK 0
#define SVCBUS_THREADPOOL_ERROR -1
typedef void (*SvcBusThreadPool_callback)( void* context );
typedef struct {
TP_CALLBACK_ENVIRON pcbe; /* platform specific field. consider opaque */
PTP_POOL pool; /* platform specific field. consider opaque */
} SvcBusThreadPool;
typedef struct {
PTP_WORK wrk; /* platform specific field. consider opaque */
void* context; /* context pointer, to be used when calling callback routine */
SvcBusThreadPool_callback callback; /* call back to call upon initialization of work in pool */
size_t thread_id; /* field used to track executor of callback thread-id. primary purpose is for testing */
} SvcBusThreadWork;
typedef struct {
PTP_TIMER timer; /* platform specific field. consider opaque */
void* context; /* context pointer to pass when invoking timer callback */
SvcBusThreadPool_callback callback; /* callback to be called every time timer elapses*/
size_t thread_id; /* field used to track executor of callback thread-id. primary purpose is for testing */
} SvcBusThreadPoolTimer;
/**
* Initializes a thread-pool subsystem into the passed SvcBusThreadPool object
*
* @param minThreads minimum number of threads to allocate to pool
* @param maxThreads maximum number of threads to allocate to pool
*
* @return SVCBUS_THREADPOOL_OK or SVCBUS_THREADPOOL_ERROR
* note: if function returns SVCBUS_THREADPOOL_ERROR no need to destroy the object with SvcBusThreadPool_destroy()
* but destructor can be called anyway
*/
int SvcBusThreadPool_init( SvcBusThreadPool* _this, unsigned int minThreads, unsigned int maxThreads );
/**
* Destroys a thread-pool object
*/
void SvcBusThreadPool_destroy( SvcBusThreadPool* _this );
/************************************/
/* Thread pool work APIs Management */
/************************************/
/**
* Initializes a ThreadWork object linked to a thread-pool previously created with SvcBusThreadPool_init()
*
* @param pool thread-pool object
* @param callback callback function to call when worker object becomes active within a specific thread of the pool
* @param context user parameter used to pass data to the callback when it's invoked
*
* @return SVCBUS_THREADPOOL_OK or SVCBUS_THREADPOOL_ERROR
* note: if function returns SVCBUS_THREADPOOL_ERROR no need to destroy the object with SvcBusThreadWork_destroy()
* but destructor can be called anyway
*/
int SvcBusThreadWork_init( SvcBusThreadWork* _this, SvcBusThreadPool* pool, SvcBusThreadPool_callback callback, void* context );
/**
* Destroys a ThreadWork object
*/
void SvcBusThreadWork_destroy( SvcBusThreadWork* _this );
/**
* Submits a ThreadWork object to the thread-pool and activates it as soon as a thread becomes available
* the same object can be submitted multiple times up to MAXULONG (Windows limitation)
*/
void SvcBusThreadWork_submit( SvcBusThreadWork* _this );
/**
* Waits for a ThreadWork object to finish its work and then returns control to caller.
* note: this is the main function used to synchronize work happening in a secondary thread with main thread
*/
void SvcBusThreadWork_wait( SvcBusThreadWork* _this );
/**
* function used internally for testing purposes that returns the threadid of the thread that actually executed the callback
* linked to the ThreadWork object
*/
size_t SvcBusThreadWork_getThreadId( SvcBusThreadWork* _this );
/********************/
/* Timer Management */
/********************/
/**
* Initializes a ThreadPoolTimer object linked to a thread-pool previously created with SvcBusThreadPool_init()
*
* @param pool thread-pool object
* @param callback callback function to call when worker object becomes active within a specific thread of the pool
* @param context user parameter used to pass data to the callback when it's invoked
* @param millis time in milliseconds elapsed to invoke callback
*
* @return SVCBUS_THREADPOOL_OK or SVCBUS_THREADPOOL_ERROR
*/
int SvcBusThreadPoolTimer_init( SvcBusThreadPoolTimer* _this, SvcBusThreadPool* pool, SvcBusThreadPool_callback callback, void* context, unsigned int millis );
/**
* destroys the SvcBusThreadPoolTimer object
* note: side effect, _this->timer is set to NULL
* this function will also wait if there's a running timer execution until it completes
* before returning control to the caller. Other pending executions are canceled
*/
void SvcBusThreadPoolTimer_destroy( SvcBusThreadPoolTimer* _this );
/**
* function used internally for testing purposes that returns the threadid of the thread that actually executed the callback
* linked to the timer object
*/
size_t SvcBusThreadPoolTimer_getThreadId( SvcBusThreadPoolTimer* _this );
#define SvcBusThreadPoolTimer_initZero( _this ) _this->timer = NULL
#define SvcBusThreadPoolTimer_isZero( _this ) ( _this->timer == NULL )
/********************/
/* Event Management */
/********************/
#define SVCBUS_EVENT_OK 0
#define SVCBUS_EVENT_ERROR -1
#define SvcBusEvent HANDLE
typedef enum SvcBusEvent_wait_result_t {
SVCBUS_WAIT_RESULT_ABANDONED = WAIT_ABANDONED,
SVCBUS_WAIT_RESULT_SIGNALED = WAIT_OBJECT_0,
SVCBUS_WAIT_RESULT_TIMEOUT = WAIT_TIMEOUT,
SVCBUS_WAIT_RESULT_FAILED = WAIT_FAILED
} SvcBusEvent_wait_result_t;
/**
* initializes a new SvcBusEvent object.
* For Windows: event will be created in manual reset mode, initial state signaled, unnamed
*/
int SvcBusEvent_init( SvcBusEvent* _this );
/**
* destroys a SvcBusEvent object.
*/
int SvcBusEvent_destroy( SvcBusEvent* _this );
/**
* signals an event
*/
int SvcBusEvent_signal( SvcBusEvent* _this );
/**
* resets an event to non-signaled state
*/
int SvcBusEvent_reset( SvcBusEvent* _this );
/**
* waits for an event to be signaled up to millis milliseconds
*/
SvcBusEvent_wait_result_t SvcBusEvent_wait( SvcBusEvent* _this, unsigned int millis );
#ifdef __cplusplus
} // extern "c"
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment