/hdbc-postgresql-helper.c

http://github.com/hdbc/hdbc-postgresql · C · 65 lines · 50 code · 9 blank · 6 comment · 7 complexity · 17e5f4f82069d61f356c8ba7b0019f96 MD5 · raw file

  1. #include <libpq-fe.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "hdbc-postgresql-helper.h"
  5. /* Things can't finalize more than once.
  6. We'd like to let people call them from the app.
  7. Yet we'd also like to be able to have a ForeignPtr finalize them.
  8. So, here's a little wrapper for things. */
  9. void PQfinish_conditional_finalizer(finalizeonce *conn);
  10. finalizeonce *wrapobjpg(void *obj, finalizeonce *parentobj) {
  11. finalizeonce *newobj;
  12. newobj = malloc(sizeof(finalizeonce));
  13. if (newobj == NULL) {
  14. fprintf(stderr, "HDBC: could not allocate wrapper!\n");
  15. return NULL;
  16. }
  17. newobj->isfinalized = 0;
  18. newobj->refcount = 1;
  19. newobj->encapobj = obj;
  20. newobj->parent = parentobj;
  21. if (parentobj != NULL)
  22. parentobj->refcount++;
  23. return newobj;
  24. }
  25. void PQfinish_app(finalizeonce *conn) {
  26. if (conn->isfinalized)
  27. return;
  28. PQfinish((PGconn *) (conn->encapobj));
  29. conn->encapobj = NULL;
  30. conn->isfinalized = 1;
  31. }
  32. void PQfinish_finalizer(finalizeonce *conn) {
  33. (conn->refcount)--;
  34. PQfinish_conditional_finalizer(conn);
  35. }
  36. void PQfinish_conditional_finalizer(finalizeonce *conn) {
  37. if (conn->refcount < 1) {
  38. PQfinish_app(conn);
  39. free(conn);
  40. }
  41. }
  42. void PQclear_app(finalizeonce *res) {
  43. if (res->isfinalized)
  44. return;
  45. PQclear((PGresult *) (res->encapobj));
  46. res->isfinalized = 1;
  47. }
  48. void PQclear_finalizer(finalizeonce *res) {
  49. PQclear_app(res);
  50. (res->refcount)--; /* Not really important since this is never a
  51. parent */
  52. (res->parent->refcount)--;
  53. PQfinish_conditional_finalizer(res->parent);
  54. free(res);
  55. }