php_gearman_client.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. /*
  2. * Gearman PHP Extension
  3. *
  4. * Copyright (C) 2008 James M. Luedke <contact@jamesluedke.com>,
  5. * Eric Day <eday@oddments.org>
  6. * All rights reserved.
  7. *
  8. * Use and distribution licensed under the PHP license. See
  9. * the LICENSE file in this directory for full text.
  10. */
  11. #include "php_gearman_task.h"
  12. #include "php_gearman_client.h"
  13. inline gearman_client_obj *gearman_client_fetch_object(zend_object *obj) {
  14. return (gearman_client_obj *)((char*)(obj) - XtOffsetOf(gearman_client_obj, std));
  15. }
  16. static void gearman_client_ctor(INTERNAL_FUNCTION_PARAMETERS) {
  17. gearman_client_obj *client;
  18. if (zend_parse_parameters_none() == FAILURE) {
  19. return;
  20. }
  21. client = Z_GEARMAN_CLIENT_P(return_value);
  22. if (gearman_client_create(&(client->client)) == NULL) {
  23. GEARMAN_EXCEPTION("Memory allocation failure", 0);
  24. }
  25. client->flags |= GEARMAN_CLIENT_OBJ_CREATED;
  26. gearman_client_add_options(&(client->client), GEARMAN_CLIENT_FREE_TASKS);
  27. gearman_client_set_workload_malloc_fn(&(client->client), _php_malloc, NULL);
  28. gearman_client_set_workload_free_fn(&(client->client), _php_free, NULL);
  29. gearman_client_set_task_context_free_fn(&(client->client), _php_task_free);
  30. }
  31. /* {{{ proto object gearman_client_create()
  32. Returns a GearmanClient object */
  33. PHP_FUNCTION(gearman_client_create) {
  34. if (object_init_ex(return_value, gearman_client_ce) != SUCCESS) {
  35. php_error_docref(NULL, E_WARNING, "Object creation failure.");
  36. RETURN_FALSE;
  37. }
  38. gearman_client_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  39. }
  40. inline zend_object *gearman_client_obj_new(zend_class_entry *ce) {
  41. gearman_client_obj *intern = ecalloc(1,
  42. sizeof(gearman_client_obj) +
  43. zend_object_properties_size(ce));
  44. zend_object_std_init(&(intern->std), ce);
  45. object_properties_init(&intern->std, ce);
  46. array_init(&intern->task_list);
  47. intern->created_tasks = 0;
  48. intern->std.handlers = &gearman_client_obj_handlers;
  49. return &intern->std;
  50. }
  51. /* {{{ proto object GearmanClient::__construct()
  52. Returns a GearmanClient object */
  53. PHP_METHOD(GearmanClient, __construct)
  54. {
  55. return_value = getThis();
  56. gearman_client_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  57. }
  58. /* }}} */
  59. /* {{{ proto object GearmanClient::__destruct()
  60. cleans up GearmanClient object */
  61. PHP_METHOD(GearmanClient, __destruct)
  62. {
  63. char *context = NULL;
  64. gearman_client_obj *intern = Z_GEARMAN_CLIENT_P(getThis());
  65. if (!intern) {
  66. return;
  67. }
  68. context = gearman_client_context(&(intern->client));
  69. efree(context);
  70. if (intern->flags & GEARMAN_CLIENT_OBJ_CREATED) {
  71. gearman_client_free(&intern->client);
  72. }
  73. // Clear Callbacks
  74. zval_dtor(&intern->zworkload_fn);
  75. zval_dtor(&intern->zcreated_fn);
  76. zval_dtor(&intern->zdata_fn);
  77. zval_dtor(&intern->zwarning_fn);
  78. zval_dtor(&intern->zstatus_fn);
  79. zval_dtor(&intern->zcomplete_fn);
  80. zval_dtor(&intern->zexception_fn);
  81. zval_dtor(&intern->zfail_fn);
  82. zval_dtor(&intern->task_list);
  83. zend_object_std_dtor(&intern->std);
  84. }
  85. /* {{{ proto int gearman_client_return_code()
  86. get last gearman_return_t */
  87. PHP_FUNCTION(gearman_client_return_code)
  88. {
  89. gearman_client_obj *obj;
  90. zval *zobj;
  91. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  92. RETURN_NULL();
  93. }
  94. obj = Z_GEARMAN_CLIENT_P(zobj);
  95. RETURN_LONG(obj->ret);
  96. }
  97. /* }}} */
  98. /* {{{ proto string gearman_client_error()
  99. Return an error string for the last error encountered. */
  100. PHP_FUNCTION(gearman_client_error) {
  101. char *error = NULL;
  102. gearman_client_obj *obj;
  103. zval *zobj;
  104. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  105. RETURN_NULL();
  106. }
  107. obj = Z_GEARMAN_CLIENT_P(zobj);
  108. error = (char *)gearman_client_error(&(obj->client));
  109. if (error) {
  110. RETURN_STRING(error)
  111. }
  112. RETURN_FALSE;
  113. }
  114. /* }}} */
  115. /* {{{ proto int gearman_client_get_errno()
  116. Value of errno in the case of a GEARMAN_ERRNO return value. */
  117. PHP_FUNCTION(gearman_client_get_errno) {
  118. gearman_client_obj *obj;
  119. zval *zobj;
  120. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  121. RETURN_NULL();
  122. }
  123. obj = Z_GEARMAN_CLIENT_P(zobj);
  124. RETURN_LONG(gearman_client_errno(&(obj->client)))
  125. }
  126. /* }}} */
  127. /* {{{ proto int gearman_client_options()
  128. Get options for a client structure. */
  129. PHP_FUNCTION(gearman_client_options) {
  130. gearman_client_obj *obj;
  131. zval *zobj;
  132. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  133. RETURN_NULL();
  134. }
  135. obj = Z_GEARMAN_CLIENT_P(zobj);
  136. RETURN_LONG(gearman_client_options(&(obj->client)))
  137. }
  138. /* }}} */
  139. /* {{{ proto void gearman_client_set_options(constant option)
  140. Set options for a client structure.
  141. NOTE: this is deprecated in gearmand */
  142. PHP_FUNCTION(gearman_client_set_options) {
  143. zend_long options;
  144. gearman_client_obj *obj;
  145. zval *zobj;
  146. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &zobj, gearman_client_ce, &options) == FAILURE) {
  147. RETURN_FALSE;
  148. }
  149. obj = Z_GEARMAN_CLIENT_P(zobj);
  150. gearman_client_set_options(&(obj->client), options);
  151. RETURN_TRUE;
  152. }
  153. /* }}} */
  154. /* {{{ proto void GearmanClient::addOptions(constant option)
  155. Set options for a client structure. */
  156. PHP_FUNCTION(gearman_client_add_options) {
  157. zend_long options;
  158. gearman_client_obj *obj;
  159. zval *zobj;
  160. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &zobj, gearman_client_ce, &options) == FAILURE) {
  161. RETURN_FALSE;
  162. }
  163. obj = Z_GEARMAN_CLIENT_P(zobj);
  164. gearman_client_add_options(&(obj->client), options);
  165. RETURN_TRUE;
  166. }
  167. /* }}} */
  168. /* {{{ proto void GearmanClient::removeOptions(constant option)
  169. Set options for a client structure. */
  170. PHP_FUNCTION(gearman_client_remove_options) {
  171. zend_long options;
  172. gearman_client_obj *obj;
  173. zval *zobj;
  174. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &zobj, gearman_client_ce, &options) == FAILURE) {
  175. RETURN_FALSE;
  176. }
  177. obj = Z_GEARMAN_CLIENT_P(zobj);
  178. gearman_client_remove_options(&(obj->client), options);
  179. RETURN_TRUE;
  180. }
  181. /* }}} */
  182. PHP_FUNCTION(gearman_client_timeout) {
  183. gearman_client_obj *obj;
  184. zval *zobj;
  185. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  186. RETURN_NULL();
  187. }
  188. obj = Z_GEARMAN_CLIENT_P(zobj);
  189. RETURN_LONG(gearman_client_timeout(&(obj->client)))
  190. }
  191. /* }}} */
  192. /* {{{ proto void gearman_client_set_timeout(object, constant timeout)
  193. Set timeout for a client structure. */
  194. PHP_FUNCTION(gearman_client_set_timeout) {
  195. zend_long timeout;
  196. gearman_client_obj *obj;
  197. zval *zobj;
  198. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &zobj, gearman_client_ce, &timeout) == FAILURE) {
  199. RETURN_FALSE;
  200. }
  201. obj = Z_GEARMAN_CLIENT_P(zobj);
  202. gearman_client_set_timeout(&(obj->client), timeout);
  203. RETURN_TRUE;
  204. }
  205. /* }}} */
  206. /* {{{ proto bool gearman_client_add_server(object client [, string host [, int
  207. * port [, bool setupExceptionHandler ]]])
  208. Add a job server to a client. This goes into a list of servers than can be used to run tasks. No socket I/O happens here, it is just added to a list. */
  209. PHP_FUNCTION(gearman_client_add_server) {
  210. char *host = NULL;
  211. size_t host_len = 0;
  212. zend_long port = 0;
  213. zend_bool setupExceptionHandler = 1;
  214. gearman_client_obj *obj;
  215. zval *zobj;
  216. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|slb",
  217. &zobj,
  218. gearman_client_ce,
  219. &host,
  220. &host_len,
  221. &port,
  222. &setupExceptionHandler) == FAILURE) {
  223. RETURN_FALSE;
  224. }
  225. obj = Z_GEARMAN_CLIENT_P(zobj);
  226. obj->ret = gearman_client_add_server(&(obj->client), host, port);
  227. if (obj->ret != GEARMAN_SUCCESS) {
  228. php_error_docref(NULL, E_WARNING, "%s",
  229. gearman_client_error(&(obj->client)));
  230. RETURN_FALSE;
  231. }
  232. if (setupExceptionHandler && !gearman_client_set_server_option(&(obj->client), "exceptions", (sizeof("exceptions") - 1))) {
  233. GEARMAN_EXCEPTION("Failed to set exception option", 0);
  234. }
  235. RETURN_TRUE;
  236. }
  237. /* }}} */
  238. /* {{{ proto bool gearman_client_add_servers(object client [, string servers [, bool setupExceptionHandler ]])
  239. Add a list of job servers to a client. This goes into a list of servers that can be used to run tasks. No socket I/O happens here, it is just added to a list. */
  240. PHP_FUNCTION(gearman_client_add_servers) {
  241. char *servers = NULL;
  242. size_t servers_len = 0;
  243. zend_bool setupExceptionHandler = 1;
  244. gearman_client_obj *obj;
  245. zval *zobj;
  246. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|sb",
  247. &zobj,
  248. gearman_client_ce,
  249. &servers,
  250. &servers_len,
  251. &setupExceptionHandler) == FAILURE) {
  252. RETURN_FALSE;
  253. }
  254. obj = Z_GEARMAN_CLIENT_P(zobj);
  255. obj->ret = gearman_client_add_servers(&(obj->client), servers);
  256. if (obj->ret != GEARMAN_SUCCESS) {
  257. php_error_docref(NULL, E_WARNING, "%s",
  258. gearman_client_error(&(obj->client)));
  259. RETURN_FALSE;
  260. }
  261. if (setupExceptionHandler && !gearman_client_set_server_option(&(obj->client), "exceptions", (sizeof("exceptions") - 1))) {
  262. GEARMAN_EXCEPTION("Failed to set exception option", 0);
  263. }
  264. RETURN_TRUE;
  265. }
  266. /* }}} */
  267. /* {{{ proto bool GearmanClient::wait()
  268. Wait for I/O activity on all connections in a client. */
  269. PHP_FUNCTION(gearman_client_wait) {
  270. gearman_client_obj *obj;
  271. zval *zobj;
  272. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  273. RETURN_FALSE;
  274. }
  275. obj = Z_GEARMAN_CLIENT_P(zobj);
  276. obj->ret = gearman_client_wait(&(obj->client));
  277. if (! PHP_GEARMAN_CLIENT_RET_OK(obj->ret)) {
  278. if (obj->ret != GEARMAN_TIMEOUT) {
  279. php_error_docref(NULL, E_WARNING, "%s",
  280. gearman_client_error(&(obj->client)));
  281. }
  282. RETURN_FALSE;
  283. }
  284. RETURN_TRUE;
  285. }
  286. /* }}} */
  287. /* {{{ proto object gearman_client_do_work_handler(void *add_task_func, object client, string function, zval workload [, string unique ])
  288. Run a task, high/normal/low dependent upon do_work_func */
  289. static void gearman_client_do_work_handler(void* (*do_work_func)(
  290. gearman_client_st *client,
  291. const char *function_name,
  292. const char *unique,
  293. const void *workload,
  294. size_t workload_size,
  295. size_t *result_size,
  296. gearman_return_t *ret_ptr
  297. ),
  298. INTERNAL_FUNCTION_PARAMETERS) {
  299. char *function_name;
  300. size_t function_name_len;
  301. char *workload;
  302. size_t workload_len;
  303. char *unique = NULL;
  304. size_t unique_len = 0;
  305. void *result;
  306. size_t result_size = 0;
  307. gearman_client_obj *obj;
  308. zval *zobj;
  309. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss|s", &zobj, gearman_client_ce,
  310. &function_name, &function_name_len,
  311. &workload, &workload_len,
  312. &unique, &unique_len) == FAILURE) {
  313. RETURN_EMPTY_STRING();
  314. }
  315. obj = Z_GEARMAN_CLIENT_P(zobj);
  316. result = (char *)(*do_work_func)(
  317. &(obj->client),
  318. function_name,
  319. unique,
  320. workload,
  321. (size_t)workload_len,
  322. &result_size,
  323. &(obj)->ret
  324. );
  325. if (! PHP_GEARMAN_CLIENT_RET_OK(obj->ret)) {
  326. php_error_docref(NULL, E_WARNING, "%s", gearman_client_error(&(obj->client)));
  327. RETURN_EMPTY_STRING();
  328. }
  329. /* NULL results are valid */
  330. if (! result) {
  331. RETURN_EMPTY_STRING();
  332. }
  333. RETURN_STRINGL((char *)result, (long) result_size);
  334. }
  335. /* }}} */
  336. /* {{{ proto string GearmanClient::doNormal(string function, string workload [, string unique ])
  337. Run a single task and return an allocated result. */
  338. PHP_FUNCTION(gearman_client_do_normal) {
  339. gearman_client_do_work_handler(gearman_client_do, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  340. }
  341. /* }}} */
  342. /* {{{ proto string GearmanClient::doHigh(object client, string function, string workload [, string unique ])
  343. Run a high priority task and return an allocated result. */
  344. PHP_FUNCTION(gearman_client_do_high) {
  345. gearman_client_do_work_handler(gearman_client_do_high, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  346. }
  347. /* }}} */
  348. /* {{{ proto array GearmanClient::doLow(object client, string function, string workload [, string unique ])
  349. Run a low priority task and return an allocated result. */
  350. PHP_FUNCTION(gearman_client_do_low) {
  351. gearman_client_do_work_handler(gearman_client_do_low, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  352. }
  353. /* }}} */
  354. /* {{{ proto object gearman_client_do_background_work_handler(void *add_task_func, object client, string function, zval workload [, string unique ])
  355. Run a task in the background, high/normal/low dependent upon do_work_func */
  356. static void gearman_client_do_background_work_handler(gearman_return_t (*do_background_work_func)(
  357. gearman_client_st *client,
  358. const char *function_name,
  359. const char *unique,
  360. const void *workload,
  361. size_t workload_size,
  362. gearman_job_handle_t job_handle
  363. ),
  364. INTERNAL_FUNCTION_PARAMETERS) {
  365. char *function_name;
  366. size_t function_name_len;
  367. char *workload;
  368. size_t workload_len;
  369. char *unique = NULL;
  370. size_t unique_len = 0;
  371. zend_string *job_handle;
  372. gearman_client_obj *obj;
  373. zval *zobj;
  374. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss|s!", &zobj, gearman_client_ce,
  375. &function_name, &function_name_len,
  376. &workload, &workload_len,
  377. &unique, &unique_len) == FAILURE) {
  378. RETURN_EMPTY_STRING();
  379. }
  380. obj = Z_GEARMAN_CLIENT_P(zobj);
  381. job_handle = zend_string_alloc(GEARMAN_JOB_HANDLE_SIZE-1, 0);
  382. obj->ret = (*do_background_work_func)(
  383. &(obj->client),
  384. (char *)function_name,
  385. (char *)unique,
  386. (void *)workload,
  387. (size_t)workload_len,
  388. job_handle->val
  389. );
  390. ZSTR_LEN(job_handle) = strnlen(ZSTR_VAL(job_handle), GEARMAN_JOB_HANDLE_SIZE-1);
  391. if (! PHP_GEARMAN_CLIENT_RET_OK(obj->ret)) {
  392. php_error_docref(NULL, E_WARNING, "%s",
  393. gearman_client_error(&(obj->client)));
  394. zend_string_release(job_handle);
  395. RETURN_EMPTY_STRING();
  396. }
  397. if (! job_handle) {
  398. zend_string_release(job_handle);
  399. RETURN_EMPTY_STRING();
  400. }
  401. RETURN_STR(job_handle);
  402. }
  403. /* }}} */
  404. /* {{{ proto string GearmanClient::doBackground(string function, string workload [, string unique ])
  405. Run a task in the background. */
  406. PHP_FUNCTION(gearman_client_do_background) {
  407. gearman_client_do_background_work_handler(gearman_client_do_background, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  408. }
  409. /* }}} */
  410. /* {{{ proto string GearmanClient::doHighBackground(string function, string workload [, string unique ])
  411. Run a high priority task in the background. */
  412. PHP_FUNCTION(gearman_client_do_high_background) {
  413. gearman_client_do_background_work_handler(gearman_client_do_high_background, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  414. }
  415. /* }}} */
  416. /* {{{ proto string GearmanClient::doLowBackground(string function, string workload [, string unique ])
  417. Run a low priority task in the background. */
  418. PHP_FUNCTION(gearman_client_do_low_background) {
  419. gearman_client_do_background_work_handler(gearman_client_do_low_background, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  420. }
  421. /* }}} */
  422. /* {{{ proto string GearmanClient::doJobHandle()
  423. Get the job handle for the running task. This should be used between repeated gearman_client_do_normal() and gearman_client_do_high() calls to get information. */
  424. PHP_FUNCTION(gearman_client_do_job_handle) {
  425. gearman_client_obj *obj;
  426. zval *zobj;
  427. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  428. RETURN_EMPTY_STRING();
  429. }
  430. obj = Z_GEARMAN_CLIENT_P(zobj);
  431. RETURN_STRING((char *)gearman_client_do_job_handle(&(obj->client)))
  432. }
  433. /* }}} */
  434. /* {{{ proto array GearmanClient::doStatus()
  435. Get the status for the running task. This should be used between repeated gearman_client_do() and gearman_client_do_high() calls to get information. */
  436. PHP_FUNCTION(gearman_client_do_status) {
  437. uint32_t numerator;
  438. uint32_t denominator;
  439. gearman_client_obj *obj;
  440. zval *zobj;
  441. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  442. RETURN_EMPTY_STRING();
  443. }
  444. obj = Z_GEARMAN_CLIENT_P(zobj);
  445. gearman_client_do_status(&(obj->client), &numerator, &denominator);
  446. array_init(return_value);
  447. add_next_index_long(return_value, (long) numerator);
  448. add_next_index_long(return_value, (long) denominator);
  449. }
  450. /* }}} */
  451. /* {{{ proto array GearmanClient::jobStatus(string job_handle)
  452. Get the status for a backgound job. */
  453. PHP_FUNCTION(gearman_client_job_status) {
  454. char *job_handle;
  455. size_t job_handle_len;
  456. bool is_known;
  457. bool is_running;
  458. uint32_t numerator;
  459. uint32_t denominator;
  460. gearman_client_obj *obj;
  461. zval *zobj;
  462. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &zobj, gearman_client_ce,
  463. &job_handle, &job_handle_len) == FAILURE) {
  464. RETURN_EMPTY_STRING();
  465. }
  466. obj = Z_GEARMAN_CLIENT_P(zobj);
  467. obj->ret = gearman_client_job_status(&(obj->client), job_handle,
  468. &is_known, &is_running,
  469. &numerator, &denominator);
  470. if (obj->ret != GEARMAN_SUCCESS && obj->ret != GEARMAN_IO_WAIT) {
  471. php_error_docref(NULL, E_WARNING, "%s",
  472. gearman_client_error(&(obj->client)));
  473. }
  474. array_init(return_value);
  475. add_next_index_bool(return_value, is_known);
  476. add_next_index_bool(return_value, is_running);
  477. add_next_index_long(return_value, (long) numerator);
  478. add_next_index_long(return_value, (long) denominator);
  479. }
  480. /* }}} */
  481. /* {{{ proto array GearmanClient::jobStatusByUniqueKey(string unique_key)
  482. Get the status for a backgound job using the unique key passed in during job submission, rather than job handle. */
  483. PHP_FUNCTION(gearman_client_job_status_by_unique_key) {
  484. char *unique_key;
  485. size_t unique_key_len;
  486. gearman_client_obj *obj;
  487. zval *zobj;
  488. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &zobj, gearman_client_ce,
  489. &unique_key, &unique_key_len) == FAILURE) {
  490. RETURN_EMPTY_STRING();
  491. }
  492. obj = Z_GEARMAN_CLIENT_P(zobj);
  493. gearman_status_t status = gearman_client_unique_status(&(obj->client), unique_key, unique_key_len);
  494. gearman_return_t rc = gearman_status_return(status);
  495. if (rc != GEARMAN_SUCCESS && rc != GEARMAN_IO_WAIT) {
  496. php_error_docref(NULL, E_WARNING, "%s",
  497. gearman_client_error(&(obj->client)));
  498. }
  499. array_init(return_value);
  500. add_next_index_bool(return_value, gearman_status_is_known(status));
  501. add_next_index_bool(return_value, gearman_status_is_running(status));
  502. add_next_index_long(return_value, (long) gearman_status_numerator(status));
  503. add_next_index_long(return_value, (long) gearman_status_denominator(status));
  504. }
  505. /* }}} */
  506. /* {{{ proto bool GearmanClient::ping(string workload)
  507. Send data to all job servers to see if they send it back. */
  508. PHP_FUNCTION(gearman_client_ping) {
  509. char *workload;
  510. size_t workload_len;
  511. gearman_client_obj *obj;
  512. zval *zobj;
  513. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &zobj, gearman_client_ce, &workload, &workload_len) == FAILURE) {
  514. RETURN_FALSE;
  515. }
  516. obj = Z_GEARMAN_CLIENT_P(zobj);
  517. obj->ret = gearman_client_echo(&(obj->client), workload, (size_t)workload_len);
  518. if (obj->ret != GEARMAN_SUCCESS && obj->ret != GEARMAN_IO_WAIT) {
  519. php_error_docref(NULL, E_WARNING, "%s",
  520. gearman_client_error(&(obj->client)));
  521. RETURN_FALSE;
  522. }
  523. RETURN_TRUE;
  524. }
  525. /* }}} */
  526. /* {{{ proto object gearman_client_add_task_handler(void *add_task_func, object client, string function, zval workload [, string unique ])
  527. Add a task to be run in parallel, background or not, high/normal/low dependent upon add_task_func. */
  528. static void gearman_client_add_task_handler(gearman_task_st* (*add_task_func)(
  529. gearman_client_st *client,
  530. gearman_task_st *task,
  531. void *context,
  532. const char *function_name,
  533. const char *unique,
  534. const void *workload,
  535. size_t workload_size,
  536. gearman_return_t *ret_ptr),
  537. INTERNAL_FUNCTION_PARAMETERS) {
  538. zval *zworkload;
  539. zval *zdata = NULL;
  540. gearman_task_obj *task;
  541. char *unique;
  542. char *function_name;
  543. size_t unique_len = 0;
  544. size_t function_name_len = 0;
  545. gearman_client_obj *obj;
  546. zval *zobj;
  547. // TODO - the documentation on php.net differs from this
  548. // As found, this doesn't allow for user to pass in context.
  549. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Osz|zs", &zobj, gearman_client_ce,
  550. &function_name, &function_name_len,
  551. &zworkload,
  552. &zdata,
  553. &unique, &unique_len
  554. ) == FAILURE) {
  555. RETURN_FALSE;
  556. }
  557. obj = Z_GEARMAN_CLIENT_P(zobj);
  558. if (unique_len == 0) {
  559. unique = NULL;
  560. }
  561. if (Z_TYPE_P(zworkload) != IS_STRING) {
  562. convert_to_string(zworkload);
  563. }
  564. /* get a task object, and prepare it for return */
  565. if (object_init_ex(return_value, gearman_task_ce) != SUCCESS) {
  566. php_error_docref(NULL, E_WARNING, "GearmanTask Object creation failure.");
  567. RETURN_FALSE;
  568. }
  569. task = Z_GEARMAN_TASK_P(return_value);
  570. if (zdata) {
  571. ZVAL_COPY(&task->zdata, zdata);
  572. }
  573. ZVAL_COPY(&task->zworkload, zworkload);
  574. /* need to store a ref to the client for later access to cb's */
  575. ZVAL_COPY(&task->zclient, zobj);
  576. /* add the task */
  577. task->task = (*add_task_func)(
  578. &(obj->client),
  579. task->task,
  580. (void *)task,
  581. function_name,
  582. unique,
  583. Z_STRVAL_P(zworkload),
  584. (size_t) Z_STRLEN_P(zworkload),
  585. &obj->ret
  586. );
  587. if (obj->ret != GEARMAN_SUCCESS) {
  588. php_error_docref(NULL, E_WARNING, "%s",
  589. gearman_client_error(&(obj->client)));
  590. RETURN_FALSE;
  591. }
  592. task->flags |= GEARMAN_TASK_OBJ_CREATED;
  593. task->task_id = ++obj->created_tasks;
  594. // prepend task to list of tasks on client obj
  595. Z_ADDREF_P(return_value);
  596. add_index_zval(&obj->task_list, task->task_id, return_value);
  597. }
  598. /* }}} */
  599. /* {{{ proto object GearmanClient::addTask(string function, zval workload [, string unique ])
  600. Add a task to be run in parallel. */
  601. PHP_FUNCTION(gearman_client_add_task) {
  602. gearman_client_add_task_handler(gearman_client_add_task, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  603. }
  604. /* }}} */
  605. /* {{{ proto object GearmanClient::addTaskHigh(string function, zval workload [, string unique ])
  606. Add a high priority task to be run in parallel. */
  607. PHP_FUNCTION(gearman_client_add_task_high) {
  608. gearman_client_add_task_handler(gearman_client_add_task_high, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  609. }
  610. /* }}} */
  611. /* {{{ proto object GearmanClient::addTaskLow(string function, zval workload [, string unique ])
  612. Add a low priority task to be run in parallel. */
  613. PHP_FUNCTION(gearman_client_add_task_low) {
  614. gearman_client_add_task_handler(gearman_client_add_task_low, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  615. }
  616. /* }}} */
  617. /* {{{ proto object GearmanClient::addTaskBackground(string function, zval workload [, string unique ])
  618. Add a background task to be run in parallel. */
  619. PHP_FUNCTION(gearman_client_add_task_background) {
  620. gearman_client_add_task_handler(gearman_client_add_task_background, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  621. }
  622. /* }}} */
  623. /* {{{ proto object GearmanClient::addTaskHighBackground(string function, zval workload [, string unique ])
  624. Add a high priority background task to be run in parallel. */
  625. PHP_FUNCTION(gearman_client_add_task_high_background) {
  626. gearman_client_add_task_handler(gearman_client_add_task_high_background, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  627. }
  628. /* }}} */
  629. /* {{{ proto object GearmanClient::addTaskLowBackground(string function, zval workload [, string unique ])
  630. Add a low priority background task to be run in parallel. */
  631. PHP_FUNCTION(gearman_client_add_task_low_background) {
  632. gearman_client_add_task_handler(gearman_client_add_task_low_background, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  633. }
  634. /* }}} */
  635. /* {{{ proto bool gearman_client_run_tasks(object client)
  636. Run tasks that have been added in parallel */
  637. PHP_FUNCTION(gearman_client_run_tasks) {
  638. gearman_client_obj *obj;
  639. zval *zobj;
  640. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  641. RETURN_FALSE;
  642. }
  643. obj = Z_GEARMAN_CLIENT_P(zobj);
  644. obj->ret = gearman_client_run_tasks(&(obj->client));
  645. if (! PHP_GEARMAN_CLIENT_RET_OK(obj->ret)) {
  646. php_error_docref(NULL, E_WARNING, "%s",
  647. gearman_client_error(&(obj->client)));
  648. RETURN_FALSE;
  649. }
  650. RETURN_TRUE;
  651. }
  652. /* }}} */
  653. /* this function is used to request status information from the gearmand
  654. * server. it will then call your predefined status callback, passing
  655. * zdata/context to it */
  656. /* {{{ proto object gearman_client_add_task_status(object client, string job_handle [, zval data])
  657. Add task to get the status for a backgound task in parallel. */
  658. PHP_FUNCTION(gearman_client_add_task_status) {
  659. zval *zdata = NULL;
  660. char *job_handle;
  661. size_t job_handle_len = 0;
  662. gearman_client_obj *obj;
  663. zval *zobj;
  664. gearman_task_obj *task;
  665. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|z", &zobj, gearman_client_ce,
  666. &job_handle, &job_handle_len,
  667. &zdata
  668. ) == FAILURE) {
  669. RETURN_FALSE;
  670. }
  671. obj = Z_GEARMAN_CLIENT_P(zobj);
  672. /* get a task object, and prepare it for return */
  673. if (object_init_ex(return_value, gearman_task_ce) != SUCCESS) {
  674. php_error_docref(NULL, E_WARNING, "GearmanTask Object creation failure.");
  675. RETURN_FALSE;
  676. }
  677. task = Z_GEARMAN_TASK_P(return_value);
  678. if (zdata) {
  679. ZVAL_COPY(&task->zdata, zdata);
  680. }
  681. /* need to store a ref to the client for later access to cb's */
  682. ZVAL_COPY(&task->zclient, zobj);
  683. /* add the task */
  684. task->task = gearman_client_add_task_status(&(obj->client),
  685. task->task,
  686. (void *)task,
  687. job_handle,
  688. &obj->ret
  689. );
  690. if (obj->ret != GEARMAN_SUCCESS) {
  691. php_error_docref(NULL, E_WARNING, "%s",
  692. gearman_client_error(&(obj->client)));
  693. RETURN_FALSE;
  694. }
  695. task->flags |= GEARMAN_TASK_OBJ_CREATED;
  696. // prepend task to list of tasks on client obj
  697. Z_ADDREF_P(return_value);
  698. add_next_index_zval(&obj->task_list, return_value);
  699. }
  700. /* }}} */
  701. /* {{{ proto bool GearmanClient::setWorkloadCallback(callback function)
  702. Callback function when workload data needs to be sent for a task. */
  703. PHP_FUNCTION(gearman_client_set_workload_callback) {
  704. zval *zworkload_fn;
  705. zend_string *callable = NULL;
  706. gearman_client_obj *obj;
  707. zval *zobj;
  708. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  709. &zworkload_fn
  710. ) == FAILURE) {
  711. RETURN_FALSE;
  712. }
  713. obj = Z_GEARMAN_CLIENT_P(zobj);
  714. /* check that the function is callable */
  715. if (! zend_is_callable(zworkload_fn, 0, &callable)) {
  716. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  717. zend_string_release(callable);
  718. RETURN_FALSE;
  719. }
  720. zend_string_release(callable);
  721. /* Defining callback again? Clean up old one first */
  722. if (!Z_ISUNDEF(obj->zworkload_fn)) {
  723. zval_dtor(&obj->zworkload_fn);
  724. }
  725. /* store the cb in client object */
  726. ZVAL_COPY(&obj->zworkload_fn, zworkload_fn);
  727. /* set the callback for php */
  728. gearman_client_set_workload_fn(&(obj->client), _php_task_workload_fn);
  729. RETURN_TRUE;
  730. }
  731. /* }}} */
  732. /* {{{ proto bool GearmanClient::setCreatedCallback(callback function)
  733. Callback function when workload data needs to be sent for a task. */
  734. PHP_FUNCTION(gearman_client_set_created_callback) {
  735. zval *zcreated_fn;
  736. zend_string *callable = NULL;
  737. gearman_client_obj *obj;
  738. zval *zobj;
  739. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  740. &zcreated_fn
  741. ) == FAILURE) {
  742. RETURN_FALSE;
  743. }
  744. obj = Z_GEARMAN_CLIENT_P(zobj);
  745. /* check that the function is callable */
  746. if (! zend_is_callable(zcreated_fn, 0, &callable)) {
  747. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  748. zend_string_release(callable);
  749. RETURN_FALSE;
  750. }
  751. zend_string_release(callable);
  752. /* Defining callback again? Clean up old one first */
  753. if (!Z_ISUNDEF(obj->zcreated_fn)) {
  754. zval_dtor(&obj->zcreated_fn);
  755. }
  756. /* store the cb in client object */
  757. ZVAL_COPY(&obj->zcreated_fn, zcreated_fn);
  758. /* set the callback for php */
  759. gearman_client_set_created_fn(&(obj->client), _php_task_created_fn);
  760. RETURN_TRUE;
  761. }
  762. /* }}} */
  763. /* {{{ proto bool GearmanClient::setDataCallback(callback function)
  764. Callback function when there is a data packet for a task. */
  765. PHP_FUNCTION(gearman_client_set_data_callback) {
  766. zval *zdata_fn;
  767. zend_string *callable = NULL;
  768. gearman_client_obj *obj;
  769. zval *zobj;
  770. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  771. &zdata_fn
  772. ) == FAILURE) {
  773. RETURN_FALSE;
  774. }
  775. obj = Z_GEARMAN_CLIENT_P(zobj);
  776. /* check that the function is callable */
  777. if (! zend_is_callable(zdata_fn, 0, &callable)) {
  778. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  779. zend_string_release(callable);
  780. RETURN_FALSE;
  781. }
  782. zend_string_release(callable);
  783. /* Defining callback again? Clean up old one first */
  784. if (!Z_ISUNDEF(obj->zdata_fn)) {
  785. zval_dtor(&obj->zdata_fn);
  786. }
  787. /* store the cb in client object */
  788. ZVAL_COPY(&obj->zdata_fn, zdata_fn);
  789. /* set the callback for php */
  790. gearman_client_set_data_fn(&(obj->client), _php_task_data_fn);
  791. RETURN_TRUE;
  792. }
  793. /* }}} */
  794. /* {{{ proto bool GearmanClient::setWarningCallback(callback function)
  795. Callback function when there is a warning packet for a task. */
  796. PHP_FUNCTION(gearman_client_set_warning_callback) {
  797. zval *zwarning_fn;
  798. zend_string *callable = NULL;
  799. gearman_client_obj *obj;
  800. zval *zobj;
  801. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  802. &zwarning_fn
  803. ) == FAILURE) {
  804. RETURN_FALSE;
  805. }
  806. obj = Z_GEARMAN_CLIENT_P(zobj);
  807. /* check that the function is callable */
  808. if (! zend_is_callable(zwarning_fn, 0, &callable)) {
  809. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  810. zend_string_release(callable);
  811. RETURN_FALSE;
  812. }
  813. zend_string_release(callable);
  814. /* Defining callback again? Clean up old one first */
  815. if (!Z_ISUNDEF(obj->zwarning_fn)) {
  816. zval_dtor(&obj->zwarning_fn);
  817. }
  818. /* store the cb in client object */
  819. ZVAL_COPY(&obj->zwarning_fn, zwarning_fn);
  820. /* set the callback for php */
  821. gearman_client_set_warning_fn(&(obj->client), _php_task_warning_fn);
  822. RETURN_TRUE;
  823. }
  824. /* }}} */
  825. /* {{{ proto bool GearmanClient::setStatusCallback(callback function)
  826. Callback function when there is a status packet for a task. */
  827. PHP_FUNCTION(gearman_client_set_status_callback) {
  828. zval *zstatus_fn;
  829. zend_string *callable = NULL;
  830. gearman_client_obj *obj;
  831. zval *zobj;
  832. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  833. &zstatus_fn
  834. ) == FAILURE) {
  835. RETURN_FALSE;
  836. }
  837. obj = Z_GEARMAN_CLIENT_P(zobj);
  838. /* check that the function is callable */
  839. if (!zend_is_callable(zstatus_fn, 0, &callable)) {
  840. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  841. zend_string_release(callable);
  842. RETURN_FALSE;
  843. }
  844. zend_string_release(callable);
  845. /* Defining callback again? Clean up old one first */
  846. if (!Z_ISUNDEF(obj->zstatus_fn)) {
  847. zval_dtor(&obj->zstatus_fn);
  848. }
  849. /* store the cb in client object */
  850. ZVAL_COPY(&obj->zstatus_fn, zstatus_fn);
  851. /* set the callback for php */
  852. gearman_client_set_status_fn(&(obj->client), _php_task_status_fn);
  853. RETURN_TRUE;
  854. }
  855. /* }}} */
  856. /* {{{ proto bool GearmanClient::setCompleteCallback(callback function)
  857. Callback function when there is a status packet for a task. */
  858. PHP_FUNCTION(gearman_client_set_complete_callback) {
  859. zval *zcomplete_fn;
  860. zend_string *callable = NULL;
  861. gearman_client_obj *obj;
  862. zval *zobj;
  863. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  864. &zcomplete_fn
  865. ) == FAILURE) {
  866. RETURN_FALSE;
  867. }
  868. obj = Z_GEARMAN_CLIENT_P(zobj);
  869. /* check that the function is callable */
  870. if (! zend_is_callable(zcomplete_fn, 0, &callable)) {
  871. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  872. zend_string_release(callable);
  873. RETURN_FALSE;
  874. }
  875. zend_string_release(callable);
  876. /* Defining callback again? Clean up old one first */
  877. if (!Z_ISUNDEF(obj->zcomplete_fn)) {
  878. zval_dtor(&obj->zcomplete_fn);
  879. }
  880. /* store the cb in client object */
  881. ZVAL_COPY(&obj->zcomplete_fn, zcomplete_fn);
  882. /* set the callback for php */
  883. gearman_client_set_complete_fn(&(obj->client), _php_task_complete_fn);
  884. RETURN_TRUE;
  885. }
  886. /* }}} */
  887. /* {{{ proto bool GearmanClient::setExceptionCallback(callback function)
  888. Callback function when there is a exception packet for a task. */
  889. PHP_FUNCTION(gearman_client_set_exception_callback) {
  890. zval *zexception_fn;
  891. zend_string *callable = NULL;
  892. gearman_client_obj *obj;
  893. zval *zobj;
  894. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  895. &zexception_fn
  896. ) == FAILURE) {
  897. RETURN_FALSE;
  898. }
  899. obj = Z_GEARMAN_CLIENT_P(zobj);
  900. if (!gearman_client_set_server_option(&(obj->client), "exceptions", (sizeof("exceptions") - 1))) {
  901. GEARMAN_EXCEPTION("Failed to set exception option", 0);
  902. }
  903. /* check that the function is callable */
  904. if (! zend_is_callable(zexception_fn, 0, &callable)) {
  905. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  906. zend_string_release(callable);
  907. RETURN_FALSE;
  908. }
  909. zend_string_release(callable);
  910. /* Defining callback again? Clean up old one first */
  911. if (!Z_ISUNDEF(obj->zexception_fn)) {
  912. zval_dtor(&obj->zexception_fn);
  913. }
  914. /* store the cb in client object */
  915. ZVAL_COPY(&obj->zexception_fn, zexception_fn);
  916. /* set the callback for php */
  917. gearman_client_set_exception_fn(&(obj->client), _php_task_exception_fn);
  918. RETURN_TRUE;
  919. }
  920. /* }}} */
  921. /* {{{ proto bool GearmanClient::setFailCallback(callback function)
  922. Callback function when there is a fail packet for a task. */
  923. PHP_FUNCTION(gearman_client_set_fail_callback) {
  924. zval *zfail_fn;
  925. zend_string *callable = NULL;
  926. gearman_client_obj *obj;
  927. zval *zobj;
  928. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", &zobj, gearman_client_ce,
  929. &zfail_fn
  930. ) == FAILURE) {
  931. RETURN_FALSE;
  932. }
  933. obj = Z_GEARMAN_CLIENT_P(zobj);
  934. /* check that the function is callable */
  935. if (! zend_is_callable(zfail_fn, 0, &callable)) {
  936. php_error_docref(NULL, E_WARNING, "function %s is not callable", callable->val);
  937. zend_string_release(callable);
  938. RETURN_FALSE;
  939. }
  940. zend_string_release(callable);
  941. /* Defining callback again? Clean up old one first */
  942. if (!Z_ISUNDEF(obj->zfail_fn)) {
  943. zval_dtor(&obj->zfail_fn);
  944. }
  945. /* Defining callback again? Clean up old one first */
  946. if (!Z_ISUNDEF(obj->zfail_fn)) {
  947. zval_dtor(&obj->zfail_fn);
  948. }
  949. /* store the cb in client object */
  950. ZVAL_COPY(&obj->zfail_fn, zfail_fn);
  951. /* set the callback for php */
  952. gearman_client_set_fail_fn(&(obj->client), _php_task_fail_fn);
  953. RETURN_TRUE;
  954. }
  955. /* }}} */
  956. /* {{{ proto void GearmanClient::clearCallbacks()
  957. Clear all task callback functions. */
  958. PHP_FUNCTION(gearman_client_clear_callbacks) {
  959. gearman_client_obj *obj;
  960. zval *zobj;
  961. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  962. RETURN_FALSE;
  963. }
  964. obj = Z_GEARMAN_CLIENT_P(zobj);
  965. gearman_client_clear_fn(&obj->client);
  966. zval_dtor(&obj->zworkload_fn);
  967. zval_dtor(&obj->zcreated_fn);
  968. zval_dtor(&obj->zdata_fn);
  969. zval_dtor(&obj->zwarning_fn);
  970. zval_dtor(&obj->zstatus_fn);
  971. zval_dtor(&obj->zcomplete_fn);
  972. zval_dtor(&obj->zexception_fn);
  973. zval_dtor(&obj->zfail_fn);
  974. RETURN_TRUE;
  975. }
  976. /* }}} */
  977. /* {{{ proto string GearmanClient::context()
  978. Get the application data */
  979. PHP_FUNCTION(gearman_client_context) {
  980. const char *data;
  981. int length = 0;
  982. gearman_client_obj *obj;
  983. zval *zobj;
  984. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  985. RETURN_FALSE;
  986. }
  987. obj = Z_GEARMAN_CLIENT_P(zobj);
  988. data = gearman_client_context(&(obj->client));
  989. if (data) {
  990. length = strlen(data);
  991. }
  992. RETURN_STRINGL(data, length);
  993. }
  994. /* }}} */
  995. /* {{{ proto bool GearmanClient::setContext(string data)
  996. Set the application data */
  997. PHP_FUNCTION(gearman_client_set_context) {
  998. char *data, *old_context;
  999. size_t data_len = 0;
  1000. gearman_client_obj *obj;
  1001. zval *zobj;
  1002. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &zobj, gearman_client_ce, &data, &data_len) == FAILURE) {
  1003. RETURN_FALSE;
  1004. }
  1005. obj = Z_GEARMAN_CLIENT_P(zobj);
  1006. old_context = gearman_client_context(&(obj->client));
  1007. efree(old_context);
  1008. gearman_client_set_context(&(obj->client), (void*) estrndup(data, data_len));
  1009. RETURN_TRUE;
  1010. }
  1011. /* }}} */
  1012. /* {{{ proto bool GearmanClient::enableExceptionHandler()
  1013. Enable exception handling to be used by exception callback function
  1014. GearmanClient::setExceptionCallback */
  1015. PHP_FUNCTION(gearman_client_enable_exception_handler) {
  1016. gearman_client_obj *obj;
  1017. zval *zobj;
  1018. if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_client_ce) == FAILURE) {
  1019. RETURN_FALSE;
  1020. }
  1021. obj = Z_GEARMAN_CLIENT_P(zobj);
  1022. if (!gearman_client_set_server_option(&(obj->client), "exceptions", (sizeof("exceptions") - 1))) {
  1023. GEARMAN_EXCEPTION("Failed to set exception option", 0);
  1024. }
  1025. RETURN_TRUE;
  1026. }
  1027. /* }}} */