php_gearman_client.c 44 KB

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