future.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #ifndef POLLABLE_H
  2. #define POLLABLE_H
  3. typedef void *(*future_poll_func)(void *env, void *data);
  4. typedef struct future (*future_then_func)(void *env, void *result);
  5. struct future {
  6. future_poll_func f;
  7. future_then_func then;
  8. void *env;
  9. };
  10. enum future_err_code {
  11. FUTURE_ERR_OK,
  12. FUTURE_ERR_MISSING_FUNC
  13. };
  14. struct future_err {
  15. enum future_err_code code;
  16. const char *name;
  17. };
  18. void *future_poll(struct future *p, void *data, struct future_err *err);
  19. void _future_err_set(struct future_err *err, enum future_err_code code);
  20. #if defined(IMP) || defined(POLLABLE_IMP)
  21. #include <stdlib.h>
  22. void *
  23. future_poll(struct future *p, void *data, struct future_err *err)
  24. {
  25. void *res = p->f(p->env, data);
  26. if ( p->then != NULL ) {
  27. if ( res == NULL ) {
  28. goto exit_ok;
  29. }
  30. {
  31. struct future new_ftr;
  32. new_ftr = p->then(p->env, res);
  33. p->f = new_ftr.f;
  34. p->env = new_ftr.env;
  35. p->then = new_ftr.then;
  36. }
  37. res = NULL;
  38. goto exit_ok;
  39. }
  40. if ( p->f == NULL ) {
  41. _future_err_set(err, FUTURE_ERR_MISSING_FUNC);
  42. return NULL;
  43. }
  44. exit_ok:
  45. _future_err_set(err, FUTURE_ERR_OK);
  46. return res;
  47. }
  48. void
  49. _future_err_set(struct future_err *err, enum future_err_code code)
  50. {
  51. if ( err == NULL ) {
  52. return ;
  53. }
  54. err->code = code;
  55. switch ( code ) {
  56. #define _FUTURE_ERR_SET_CASE(c) case c: err->name = #c; break
  57. _FUTURE_ERR_SET_CASE(FUTURE_ERR_OK);
  58. _FUTURE_ERR_SET_CASE(FUTURE_ERR_MISSING_FUNC);
  59. #undef _FUTURE_ERR_SET_CASE
  60. }
  61. }
  62. #endif /* defined(IMP) || defined(POLLABLE_IMP) */
  63. #endif /* POLLABLE_H */