blocking_step.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Copyright (c) 2018 David Crawshaw <david@zentus.com>
  2. //
  3. // Permission to use, copy, modify, and distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8. // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10. // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11. // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12. // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13. // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14. // This file defines the wait_for_unlock_notify function.
  15. // See the documentation on Stmt.Step.
  16. #include <blocking_step.h>
  17. #include <stdlib.h>
  18. unlock_note* unlock_note_alloc() {
  19. unlock_note* un = (unlock_note*)malloc(sizeof(unlock_note));
  20. pthread_mutex_init(&un->mu, 0);
  21. pthread_cond_init(&un->cond, 0);
  22. return un;
  23. }
  24. void unlock_note_free(unlock_note* un) {
  25. pthread_cond_destroy(&un->cond);
  26. pthread_mutex_destroy(&un->mu);
  27. free(un);
  28. }
  29. void unlock_note_fire(unlock_note* un) {
  30. pthread_mutex_lock(&un->mu);
  31. un->fired = 1;
  32. pthread_cond_signal(&un->cond);
  33. pthread_mutex_unlock(&un->mu);
  34. }
  35. static void unlock_notify_cb(void **apArg, int nArg) {
  36. for(int i=0; i < nArg; i++) {
  37. unlock_note_fire((unlock_note*)apArg[i]);
  38. }
  39. }
  40. int wait_for_unlock_notify(sqlite3 *db, unlock_note* un) {
  41. un->fired = 0;
  42. int res = sqlite3_unlock_notify(db, unlock_notify_cb, (void *)un);
  43. if (res == SQLITE_OK) {
  44. pthread_mutex_lock(&un->mu);
  45. if (!un->fired) {
  46. pthread_cond_wait(&un->cond, &un->mu);
  47. }
  48. pthread_mutex_unlock(&un->mu);
  49. }
  50. return res;
  51. }