mysqlnd_plugin.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Authors: Andrey Hristov <andrey@php.net> |
  14. | Ulf Wendel <uw@php.net> |
  15. +----------------------------------------------------------------------+
  16. */
  17. #include "php.h"
  18. #include "mysqlnd.h"
  19. #include "mysqlnd_priv.h"
  20. #include "mysqlnd_statistics.h"
  21. #include "mysqlnd_debug.h"
  22. /*--------------------------------------------------------------------*/
  23. #if MYSQLND_DBG_ENABLED == 1
  24. static enum_func_status mysqlnd_example_plugin_end(void * p);
  25. static MYSQLND_STATS * mysqlnd_plugin_example_stats = NULL;
  26. enum mysqlnd_plugin_example_collected_stats
  27. {
  28. EXAMPLE_STAT1,
  29. EXAMPLE_STAT2,
  30. EXAMPLE_STAT_LAST
  31. };
  32. static const MYSQLND_STRING mysqlnd_plugin_example_stats_values_names[EXAMPLE_STAT_LAST] =
  33. {
  34. { MYSQLND_STR_W_LEN("stat1") },
  35. { MYSQLND_STR_W_LEN("stat2") }
  36. };
  37. static struct st_mysqlnd_typeii_plugin_example mysqlnd_example_plugin =
  38. {
  39. {
  40. MYSQLND_PLUGIN_API_VERSION,
  41. "example",
  42. 10001L,
  43. "1.00.01",
  44. "PHP License",
  45. "Andrey Hristov <andrey@php.net>",
  46. {
  47. NULL, /* will be filled later */
  48. mysqlnd_plugin_example_stats_values_names,
  49. },
  50. {
  51. mysqlnd_example_plugin_end
  52. }
  53. },
  54. NULL, /* methods */
  55. 0
  56. };
  57. /* {{{ mysqlnd_example_plugin_end */
  58. static
  59. enum_func_status mysqlnd_example_plugin_end(void * p)
  60. {
  61. struct st_mysqlnd_typeii_plugin_example * plugin = (struct st_mysqlnd_typeii_plugin_example *) p;
  62. DBG_ENTER("mysqlnd_example_plugin_end");
  63. mysqlnd_stats_end(plugin->plugin_header.plugin_stats.values, 1);
  64. plugin->plugin_header.plugin_stats.values = NULL;
  65. DBG_RETURN(PASS);
  66. }
  67. /* }}} */
  68. /* {{{ mysqlnd_example_plugin_register */
  69. void
  70. mysqlnd_example_plugin_register(void)
  71. {
  72. mysqlnd_stats_init(&mysqlnd_plugin_example_stats, EXAMPLE_STAT_LAST, 1);
  73. mysqlnd_example_plugin.plugin_header.plugin_stats.values = mysqlnd_plugin_example_stats;
  74. mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_example_plugin);
  75. }
  76. /* }}} */
  77. #endif /* MYSQLND_DBG_ENABLED == 1 */
  78. /*--------------------------------------------------------------------*/
  79. static HashTable mysqlnd_registered_plugins;
  80. static unsigned int mysqlnd_plugins_counter = 0;
  81. /* {{{ mysqlnd_plugin_subsystem_init */
  82. void
  83. mysqlnd_plugin_subsystem_init(void)
  84. {
  85. zend_hash_init(&mysqlnd_registered_plugins, 4 /* initial hash size */, NULL /* hash_func */, NULL /* dtor */, TRUE /* pers */);
  86. }
  87. /* }}} */
  88. /* {{{ mysqlnd_plugin_end_apply_func */
  89. int
  90. mysqlnd_plugin_end_apply_func(zval *el)
  91. {
  92. struct st_mysqlnd_plugin_header * plugin_header = (struct st_mysqlnd_plugin_header *)Z_PTR_P(el);
  93. if (plugin_header->m.plugin_shutdown) {
  94. plugin_header->m.plugin_shutdown(plugin_header);
  95. }
  96. return ZEND_HASH_APPLY_REMOVE;
  97. }
  98. /* }}} */
  99. /* {{{ mysqlnd_plugin_subsystem_end */
  100. void
  101. mysqlnd_plugin_subsystem_end(void)
  102. {
  103. zend_hash_apply(&mysqlnd_registered_plugins, mysqlnd_plugin_end_apply_func);
  104. zend_hash_destroy(&mysqlnd_registered_plugins);
  105. }
  106. /* }}} */
  107. /* {{{ mysqlnd_plugin_register */
  108. PHPAPI unsigned int mysqlnd_plugin_register(void)
  109. {
  110. return mysqlnd_plugin_register_ex(NULL);
  111. }
  112. /* }}} */
  113. /* {{{ mysqlnd_plugin_register_ex */
  114. PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header * plugin)
  115. {
  116. if (plugin) {
  117. if (plugin->plugin_api_version == MYSQLND_PLUGIN_API_VERSION) {
  118. zend_hash_str_update_ptr(&mysqlnd_registered_plugins, plugin->plugin_name, strlen(plugin->plugin_name), plugin);
  119. } else {
  120. php_error_docref(NULL, E_WARNING, "Plugin API version mismatch while loading plugin %s. Expected %d, got %d",
  121. plugin->plugin_name, MYSQLND_PLUGIN_API_VERSION, plugin->plugin_api_version);
  122. return 0xCAFE;
  123. }
  124. }
  125. return mysqlnd_plugins_counter++;
  126. }
  127. /* }}} */
  128. /* {{{ mysqlnd_plugin_find */
  129. PHPAPI void * mysqlnd_plugin_find(const char * const name)
  130. {
  131. void * plugin;
  132. if ((plugin = zend_hash_str_find_ptr(&mysqlnd_registered_plugins, name, strlen(name))) != NULL) {
  133. return plugin;
  134. }
  135. return NULL;
  136. }
  137. /* }}} */
  138. /* {{{ mysqlnd_plugin_apply_with_argument */
  139. PHPAPI void mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, void * argument)
  140. {
  141. zval *val;
  142. int result;
  143. ZEND_HASH_FOREACH_VAL(&mysqlnd_registered_plugins, val) {
  144. result = apply_func(val, argument);
  145. if (result & ZEND_HASH_APPLY_REMOVE) {
  146. php_error_docref(NULL, E_WARNING, "mysqlnd_plugin_apply_with_argument must not remove table entries");
  147. }
  148. if (result & ZEND_HASH_APPLY_STOP) {
  149. break;
  150. }
  151. } ZEND_HASH_FOREACH_END();
  152. }
  153. /* }}} */
  154. /* {{{ mysqlnd_plugin_count */
  155. PHPAPI unsigned int mysqlnd_plugin_count(void)
  156. {
  157. return mysqlnd_plugins_counter;
  158. }
  159. /* }}} */