sp_uid.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <winpr/synch.h>
  2. #include "precompile.h"
  3. #include "sp_uid.h"
  4. #include "spinlock.h"
  5. #include "memutil.h"
  6. #include "y2k_time.h"
  7. #include "dbgutil.h"
  8. struct sp_uid_generator_t
  9. {
  10. unsigned short app_id;
  11. lock_t lock;
  12. struct _sp_uid_t last_id;
  13. int mt;
  14. };
  15. sp_uid_generator_t *sp_uid_generator_create(unsigned short app_id, int mt)
  16. {
  17. sp_uid_generator_t *uid_gen = MALLOC_T(sp_uid_generator_t);
  18. if (uid_gen) {
  19. uid_gen->app_id = app_id;
  20. uid_gen->mt = mt;
  21. if (mt) {
  22. fastlock_init(uid_gen->lock);
  23. }
  24. uid_gen->last_id.app_id = app_id;
  25. uid_gen->last_id.dsn = 0;
  26. uid_gen->last_id.tick = y2k_time_now();
  27. }
  28. return uid_gen;
  29. }
  30. void sp_uid_generator_destroy(sp_uid_generator_t *uid)
  31. {
  32. if (uid->mt) {
  33. fastlock_term(uid->lock);
  34. }
  35. free(uid);
  36. }
  37. sp_uid_t sp_uid_generator_new_id(sp_uid_generator_t *uid)
  38. {
  39. struct _sp_uid_t r;
  40. TOOLKIT_ASSERT(uid);
  41. r.app_id = uid->app_id;
  42. repeat:
  43. r.tick = y2k_time_now();
  44. if (uid->mt) {
  45. fastlock_enter(uid->lock);
  46. }
  47. if (r.tick == uid->last_id.tick) {
  48. r.dsn = uid->last_id.dsn + 1;
  49. if (r.dsn == 0) {
  50. if (uid->mt) {
  51. fastlock_leave(uid->lock);
  52. }
  53. Sleep(1);
  54. goto repeat;
  55. }
  56. } else {
  57. r.dsn = 0;
  58. }
  59. uid->last_id.dsn = r.dsn;
  60. uid->last_id.tick = r.tick;
  61. if (uid->mt) {
  62. fastlock_leave(uid->lock);
  63. }
  64. return r.id;
  65. }
  66. sp_uid_t sp_uid_make(unsigned short app_id)
  67. {
  68. struct _sp_uid_t r;
  69. r.app_id = app_id;
  70. r.dsn = 0;
  71. r.tick = y2k_time_now();
  72. return r.id;
  73. }
  74. sp_uid_t sp_uid_update(sp_uid_t t)
  75. {
  76. y2k_time_t now;
  77. struct _sp_uid_t r;
  78. r.id = t;
  79. repeat:
  80. now = y2k_time_now();
  81. if (now == r.tick) {
  82. r.dsn++;
  83. if (r.dsn == 0) {
  84. Sleep(1);
  85. goto repeat;
  86. }
  87. } else {
  88. r.dsn = 0;
  89. r.tick = now;
  90. }
  91. return r.id;
  92. }