Browse Source

Provide a cg_completion_timeout helper function for unreliable functions that takes arbitrary functions and parameters and reliably returns.

nfactor-troky
ckolivas 11 years ago
parent
commit
f826e35765
  1. 41
      util.c
  2. 2
      util.h

41
util.c

@ -2485,3 +2485,44 @@ void _cgsem_destroy(cgsem_t *cgsem)
sem_destroy(cgsem); sem_destroy(cgsem);
} }
#endif #endif
/* Provide a completion_timeout helper function for unreliable functions that
* may die due to driver issues etc that time out if the function fails and
* can then reliably return. */
struct cg_completion {
cgsem_t cgsem;
void (*fn)(void *fnarg);
void *fnarg;
};
void *completion_thread(void *arg)
{
struct cg_completion *cgc = (struct cg_completion *)arg;
pthread_detach(pthread_self());
cgc->fn(cgc->fnarg);
cgsem_post(&cgc->cgsem);
return NULL;
}
bool _cg_completion_timeout(void *fn, void *fnarg, int timeout, const char *file, const char *func, const int line)
{
struct cg_completion *cgc;
pthread_t pthread;
bool ret;
cgc = malloc(sizeof(struct cg_completion));
if (unlikely(!cgc))
return false;
cgsem_init(&cgc->cgsem);
cgc->fn = fn;
cgc->fnarg = fnarg;
pthread_create(&pthread, NULL, completion_thread, (void *)cgc);
ret = cgsem_mswait(&cgc->cgsem, timeout);
if (ret)
free(cgc);
return ret;
}

2
util.h

@ -134,12 +134,14 @@ void _cgsem_post(cgsem_t *cgsem, const char *file, const char *func, const int l
void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int line); void _cgsem_wait(cgsem_t *cgsem, const char *file, const char *func, const int line);
int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line); int _cgsem_mswait(cgsem_t *cgsem, int ms, const char *file, const char *func, const int line);
void _cgsem_destroy(cgsem_t *cgsem); void _cgsem_destroy(cgsem_t *cgsem);
bool _cg_completion_timeout(void *fn, void *fnarg, int timeout, const char *file, const char *func, const int line);
#define cgsem_init(_sem) _cgsem_init(_sem, __FILE__, __func__, __LINE__) #define cgsem_init(_sem) _cgsem_init(_sem, __FILE__, __func__, __LINE__)
#define cgsem_post(_sem) _cgsem_post(_sem, __FILE__, __func__, __LINE__) #define cgsem_post(_sem) _cgsem_post(_sem, __FILE__, __func__, __LINE__)
#define cgsem_wait(_sem) _cgsem_wait(_sem, __FILE__, __func__, __LINE__) #define cgsem_wait(_sem) _cgsem_wait(_sem, __FILE__, __func__, __LINE__)
#define cgsem_mswait(_sem, _timeout) _cgsem_mswait(_sem, _timeout, __FILE__, __func__, __LINE__) #define cgsem_mswait(_sem, _timeout) _cgsem_mswait(_sem, _timeout, __FILE__, __func__, __LINE__)
#define cgsem_destroy(_sem) _cgsem_destroy(_sem) #define cgsem_destroy(_sem) _cgsem_destroy(_sem)
#define cg_completion_timeout(fn, fnarg, timeout) _cg_completion_timeout(fn, fnarg, timeout, __FILE__, __func__, __LINE__)
/* Align a size_t to 4 byte boundaries for fussy arches */ /* Align a size_t to 4 byte boundaries for fussy arches */
static inline void align_len(size_t *len) static inline void align_len(size_t *len)

Loading…
Cancel
Save