php_gearman_client.c 44 KB

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