You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

snowdrift.c 7.6 kB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. +----------------------------------------------------------------------+
  3. | snowdrift |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: 63851587@qq.com |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "php.h"
  23. #include "php_ini.h"
  24. #include "zend_exceptions.h"
  25. #include "ext/standard/info.h"
  26. #include "src/snowflake/shm.h"
  27. #include "php_snowdrift.h"
  28. #include "src/snowflake/snowflake.h"
  29. /* True global resources - no need for thread safety here */
  30. static struct shm shmctx;
  31. static snowflake *sf;
  32. zend_class_entry snowdrift_ce;
  33. uint8_t num = 0;
  34. /* {{{ PHP_INI */
  35. PHP_INI_BEGIN()
  36. STD_PHP_INI_ENTRY("snowdrift.Method", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, Method, zend_snowdrift_globals, snowdrift_globals)
  37. STD_PHP_INI_ENTRY("snowdrift.BaseTime", "1582136402000", PHP_INI_SYSTEM, OnUpdateLongGEZero, BaseTime, zend_snowdrift_globals, snowdrift_globals)
  38. STD_PHP_INI_ENTRY("snowdrift.WorkerId", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerId, zend_snowdrift_globals, snowdrift_globals)
  39. STD_PHP_INI_ENTRY("snowdrift.WorkerIdNum", "1", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerIdNum, zend_snowdrift_globals, snowdrift_globals)
  40. STD_PHP_INI_ENTRY("snowdrift.WorkerIdBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, WorkerIdBitLength, zend_snowdrift_globals, snowdrift_globals)
  41. STD_PHP_INI_ENTRY("snowdrift.SeqBitLength", "6", PHP_INI_SYSTEM, OnUpdateLongGEZero, SeqBitLength, zend_snowdrift_globals, snowdrift_globals)
  42. STD_PHP_INI_ENTRY("snowdrift.MaxSeqNumber", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, MaxSeqNumber, zend_snowdrift_globals, snowdrift_globals)
  43. STD_PHP_INI_ENTRY("snowdrift.MinSeqNumber", "0", PHP_INI_SYSTEM, OnUpdateLongGEZero, MinSeqNumber, zend_snowdrift_globals, snowdrift_globals)
  44. STD_PHP_INI_ENTRY("snowdrift.TopOverCostCount", "2000", PHP_INI_SYSTEM, OnUpdateLongGEZero, TopOverCostCount, zend_snowdrift_globals, snowdrift_globals)
  45. PHP_INI_END()
  46. /* }}} */
  47. static int snowdrift_init()
  48. {
  49. num = (-1L << SD_G(WorkerIdBitLength)) ^ -1L;
  50. if (SD_G(WorkerIdNum) < num)
  51. {
  52. num = SD_G(WorkerIdNum);
  53. }
  54. shmctx.size = num * sizeof(snowflake);
  55. if (shm_alloc(&shmctx) == -1)
  56. {
  57. zend_throw_exception_ex(NULL, 0, "shared memory malloc failed");
  58. RETURN_FALSE;
  59. }
  60. if (SD_G(MaxSeqNumber) <= SD_G(MinSeqNumber))
  61. {
  62. zend_throw_exception_ex(NULL, 0, "MaxSeqNumber must GE then MinSeqNumber");
  63. RETURN_FALSE;
  64. }
  65. bzero(shmctx.addr, num * sizeof(snowflake));
  66. sf = (snowflake *)shmctx.addr;
  67. for (int i = 0; i < num; i++)
  68. {
  69. snowflake *tmp = (sf + i);
  70. tmp->Method = SD_G(Method);
  71. tmp->BaseTime = SD_G(BaseTime);
  72. tmp->WorkerId = i + 1;
  73. tmp->WorkerIdBitLength = SD_G(WorkerIdBitLength);
  74. tmp->SeqBitLength = SD_G(SeqBitLength);
  75. tmp->MaxSeqNumber = SD_G(MaxSeqNumber);
  76. tmp->MinSeqNumber = SD_G(MinSeqNumber);
  77. tmp->TopOverCostCount = SD_G(TopOverCostCount);
  78. Config(tmp);
  79. }
  80. return SUCCESS;
  81. }
  82. PHP_METHOD(snowdrift, NextId)
  83. {
  84. zend_long wid = SD_G(WorkerId);
  85. if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &wid) == FAILURE)
  86. {
  87. RETURN_FALSE;
  88. }
  89. wid--;
  90. if (wid < 0 || wid > num - 1)
  91. {
  92. zend_throw_exception_ex(NULL, 0, "wid error! wid between 0 and %d", num - 1);
  93. RETURN_NULL();
  94. }
  95. snowflake *flake = (sf + wid);
  96. RETURN_LONG(NextId(flake));
  97. }
  98. /** 这种方式性能比不上PHP直接循环调用NextId快
  99. */
  100. PHP_METHOD(snowdrift, NextNumId)
  101. {
  102. zend_long num = 1;
  103. zend_long wid = SD_G(WorkerId);
  104. if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|l", &num, &wid) == FAILURE)
  105. {
  106. RETURN_FALSE;
  107. }
  108. wid--;
  109. if (wid < 0 || wid > num - 1)
  110. {
  111. zend_throw_exception_ex(NULL, 0, "wid error! wid between 0 and %d", num - 1);
  112. RETURN_NULL();
  113. }
  114. snowflake *flake = (sf + wid);
  115. array_init(return_value);
  116. for (int i = 0; i < num; i++)
  117. {
  118. add_next_index_long(return_value, NextId(flake));
  119. }
  120. }
  121. /* {{{ PHP_MSHUTDOWN_FUNCTION
  122. */
  123. PHP_MSHUTDOWN_FUNCTION(snowdrift)
  124. {
  125. UNREGISTER_INI_ENTRIES();
  126. shm_free(&shmctx);
  127. return SUCCESS;
  128. }
  129. /* }}} */
  130. /* Remove if there's nothing to do at request start */
  131. /* {{{ PHP_RINIT_FUNCTION
  132. */
  133. PHP_RINIT_FUNCTION(snowdrift)
  134. {
  135. #if defined(COMPILE_DL_SNOWFLAKE) && defined(ZTS)
  136. ZEND_TSRMLS_CACHE_UPDATE();
  137. #endif
  138. return SUCCESS;
  139. }
  140. /* }}} */
  141. /* Remove if there's nothing to do at request end */
  142. /* {{{ PHP_RSHUTDOWN_FUNCTION
  143. */
  144. PHP_RSHUTDOWN_FUNCTION(snowdrift)
  145. {
  146. return SUCCESS;
  147. }
  148. /* }}} */
  149. /* {{{ PHP_MINFO_FUNCTION
  150. */
  151. PHP_MINFO_FUNCTION(snowdrift)
  152. {
  153. php_info_print_table_start();
  154. php_info_print_table_header(2, "snowfrift support", "enabled");
  155. php_info_print_table_row(2, "Version", PHP_SNOWDRIFT_VERSION);
  156. php_info_print_table_end();
  157. /* Remove comments if you have entries in php.ini */
  158. DISPLAY_INI_ENTRIES();
  159. }
  160. /* }}} */
  161. /* {{{ arginfo
  162. */
  163. ZEND_BEGIN_ARG_INFO(arginfo_snowdrift_void, 0)
  164. ZEND_END_ARG_INFO()
  165. ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextid, 0, 0, 1)
  166. ZEND_ARG_INFO(0, wid)
  167. ZEND_END_ARG_INFO()
  168. ZEND_BEGIN_ARG_INFO_EX(arginfo_snowdrift_nextnumid, 0, 0, 1)
  169. ZEND_ARG_INFO(0, num)
  170. ZEND_ARG_INFO(0, wid)
  171. ZEND_END_ARG_INFO()
  172. /* }}} */
  173. /* {{{ snowdrift_functions[]
  174. *
  175. * Every user visible function must have an entry in snowdrift_functions[].
  176. */
  177. const zend_function_entry snowdrift_functions[] = {
  178. PHP_FE_END /* Must be the last line in snowdrift_functions[] */
  179. };
  180. /* }}} */
  181. /* {{{ snowdrift_method[]
  182. *
  183. * Every user visible function must have an entry in snowdrift_functions[].
  184. */
  185. static const zend_function_entry snowdrift_methods[] = {
  186. PHP_ME(snowdrift, NextId, arginfo_snowdrift_nextid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
  187. PHP_ME(snowdrift, NextNumId, arginfo_snowdrift_nextnumid, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
  188. /* }}} */
  189. /* {{{ PHP_MINIT_FUNCTION
  190. */
  191. PHP_MINIT_FUNCTION(snowdrift)
  192. {
  193. INIT_CLASS_ENTRY(snowdrift_ce, "snowdrift", snowdrift_methods);
  194. REGISTER_INI_ENTRIES();
  195. zend_register_internal_class(&snowdrift_ce);
  196. if (snowdrift_init() == FAILURE)
  197. {
  198. return FAILURE;
  199. }
  200. return SUCCESS;
  201. }
  202. /* }}} */
  203. /* {{{ snowdrift_module_entry
  204. */
  205. zend_module_entry snowdrift_module_entry = {
  206. STANDARD_MODULE_HEADER,
  207. "snowdrift",
  208. snowdrift_functions,
  209. PHP_MINIT(snowdrift),
  210. PHP_MSHUTDOWN(snowdrift),
  211. PHP_RINIT(snowdrift), /* Replace with NULL if there's nothing to do at
  212. request start */
  213. PHP_RSHUTDOWN(snowdrift), /* Replace with NULL if there's nothing to do at
  214. request end */
  215. PHP_MINFO(snowdrift),
  216. PHP_SNOWDRIFT_VERSION,
  217. STANDARD_MODULE_PROPERTIES};
  218. /* }}} */
  219. #ifdef COMPILE_DL_SNOWDRIFT
  220. #ifdef ZTS
  221. ZEND_TSRMLS_CACHE_DEFINE()
  222. #endif
  223. ZEND_GET_MODULE(snowdrift)
  224. #endif