Skip to content

Commit f6db3ad

Browse files
committed
Add rest of the callbacks
1 parent 5735f7f commit f6db3ad

File tree

5 files changed

+171
-39
lines changed

5 files changed

+171
-39
lines changed

Diff for: php_memcached.c

+23-2
Original file line numberDiff line numberDiff line change
@@ -3415,9 +3415,22 @@ static int php_memc_do_result_callback(zval *zmemc_obj, zend_fcall_info *fci,
34153415
}
34163416
/* }}} */
34173417

3418+
static
3419+
void s_destroy_cb (zend_fcall_info *fci)
3420+
{
3421+
if (fci->size > 0) {
3422+
zval_ptr_dtor(&fci->function_name);
3423+
if (fci->object_ptr != NULL) {
3424+
zval_ptr_dtor(&fci->object_ptr);
3425+
}
3426+
}
3427+
}
3428+
34183429
static
34193430
PHP_METHOD(MemcachedServer, run)
34203431
{
3432+
int i;
3433+
zend_bool rc;
34213434
char *address;
34223435
int address_len;
34233436

@@ -3427,9 +3440,15 @@ PHP_METHOD(MemcachedServer, run)
34273440
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &address, &address_len) == FAILURE) {
34283441
return;
34293442
}
3430-
php_memc_proto_handler_run (intern->handler, address);
3431-
}
34323443

3444+
rc = php_memc_proto_handler_run (intern->handler, address);
3445+
3446+
for (i = MEMC_SERVER_ON_MIN + 1; i < MEMC_SERVER_ON_MAX; i++) {
3447+
s_destroy_cb (&MEMC_G(server.callbacks) [i].fci);
3448+
}
3449+
3450+
RETURN_BOOL(rc);
3451+
}
34333452

34343453
static
34353454
PHP_METHOD(MemcachedServer, on)
@@ -3452,6 +3471,8 @@ PHP_METHOD(MemcachedServer, on)
34523471
}
34533472

34543473
if (fci.size > 0) {
3474+
s_destroy_cb (&MEMC_G(server.callbacks) [event].fci);
3475+
34553476
MEMC_G(server.callbacks) [event].fci = fci;
34563477
MEMC_G(server.callbacks) [event].fci_cache = fci_cache;
34573478

Diff for: php_memcached_server.c

+138-36
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ long s_invoke_php_callback (php_memc_server_cb_t *cb, zval ***params, ssize_t pa
7878
cb->fci.retval_ptr_ptr = &retval_ptr;
7979

8080
if (zend_call_function(&(cb->fci), &(cb->fci_cache) TSRMLS_CC) == FAILURE) {
81-
php_error_docref (NULL TSRMLS_CC, E_WARNING, "Failed to invoke callback %s()", Z_STRVAL_P (cb->fci.function_name));
81+
php_error_docref (NULL TSRMLS_CC, E_WARNING, "Failed to invoke callback");
8282
}
8383
if (retval_ptr) {
8484
convert_to_long (retval_ptr);
@@ -91,10 +91,10 @@ long s_invoke_php_callback (php_memc_server_cb_t *cb, zval ***params, ssize_t pa
9191
// memcached protocol callbacks
9292
static
9393
protocol_binary_response_status s_add_handler(const void *cookie, const void *key, uint16_t key_len, const void *data,
94-
uint32_t data_len, uint32_t flags, uint32_t exptime, uint64_t *cas)
94+
uint32_t data_len, uint32_t flags, uint32_t exptime, uint64_t *result_cas)
9595
{
9696
protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
97-
zval *zcookie, *zkey, *zvalue, *zflags, *zexptime, *zcas;
97+
zval *zcookie, *zkey, *zvalue, *zflags, *zexptime, *zresult_cas;
9898
zval **params [6];
9999

100100
if (!MEMC_HAS_CB(MEMC_SERVER_ON_ADD)) {
@@ -115,29 +115,26 @@ protocol_binary_response_status s_add_handler(const void *cookie, const void *ke
115115
MAKE_STD_ZVAL(zexptime);
116116
ZVAL_LONG(zexptime, exptime);
117117

118-
MAKE_STD_ZVAL(zcas);
119-
ZVAL_NULL(zcas);
118+
MAKE_STD_ZVAL(zresult_cas);
119+
ZVAL_NULL(zresult_cas);
120120

121121
params [0] = &zcookie;
122122
params [1] = &zkey;
123123
params [2] = &zvalue;
124124
params [3] = &zflags;
125125
params [4] = &zexptime;
126-
params [5] = &zcas;
126+
params [5] = &zresult_cas;
127127

128128
retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_ADD), params, 6);
129129

130-
if (Z_TYPE_P(zcas) != IS_NULL) {
131-
convert_to_double (zcas);
132-
*cas = (uint64_t) Z_DVAL_P(zcas);
133-
}
130+
MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas);
134131

135132
zval_ptr_dtor (&zcookie);
136133
zval_ptr_dtor (&zkey);
137134
zval_ptr_dtor (&zvalue);
138135
zval_ptr_dtor (&zflags);
139136
zval_ptr_dtor (&zexptime);
140-
zval_ptr_dtor (&zcas);
137+
zval_ptr_dtor (&zresult_cas);
141138

142139
return retval;
143140
}
@@ -519,6 +516,82 @@ protocol_binary_response_status s_set_handler (const void *cookie, const void *k
519516
s_set_replace_handler (MEMC_SERVER_ON_SET, cookie, key, key_len, data, data_len, flags, expiration, cas, result_cas);
520517
}
521518

519+
static
520+
protocol_binary_response_status s_stat_handler (const void *cookie, const void *key, uint16_t key_len,
521+
memcached_binary_protocol_stat_response_handler response_handler)
522+
{
523+
zval **params [3];
524+
protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
525+
zval *zcookie, *zkey, *zbody;
526+
527+
if (!MEMC_HAS_CB(MEMC_SERVER_ON_STAT)) {
528+
return retval;
529+
}
530+
531+
MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie);
532+
533+
MAKE_STD_ZVAL(zkey);
534+
ZVAL_STRINGL(zkey, key, key_len, 1);
535+
536+
MAKE_STD_ZVAL(zbody);
537+
ZVAL_NULL(zbody);
538+
539+
params [0] = &zcookie;
540+
params [1] = &zkey;
541+
params [2] = &zbody;
542+
543+
retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_STAT), params, 3);
544+
545+
if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
546+
if (Z_TYPE_P (zbody) == IS_NULL) {
547+
retval = response_handler(cookie, NULL, 0, NULL, 0);
548+
}
549+
else {
550+
if (Z_TYPE_P (zbody) != IS_STRING) {
551+
convert_to_string (zbody);
552+
}
553+
retval = response_handler(cookie, key, key_len, Z_STRVAL_P (zbody), (uint32_t) Z_STRLEN_P (zbody));
554+
}
555+
}
556+
zval_ptr_dtor (&zcookie);
557+
zval_ptr_dtor (&zkey);
558+
zval_ptr_dtor (&zbody);
559+
return retval;
560+
}
561+
562+
static
563+
protocol_binary_response_status s_version_handler (const void *cookie,
564+
memcached_binary_protocol_version_response_handler response_handler)
565+
{
566+
zval **params [2];
567+
protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND;
568+
zval *zcookie, *zversion;
569+
570+
if (!MEMC_HAS_CB(MEMC_SERVER_ON_VERSION)) {
571+
return retval;
572+
}
573+
574+
MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie);
575+
576+
MAKE_STD_ZVAL(zversion);
577+
ZVAL_NULL(zversion);
578+
579+
params [0] = &zcookie;
580+
params [1] = &zversion;
581+
582+
retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_VERSION), params, 2);
583+
584+
if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
585+
if (Z_TYPE_P (zversion) != IS_STRING) {
586+
convert_to_string (zversion);
587+
}
588+
589+
retval = response_handler (cookie, Z_STRVAL_P(zversion), (uint32_t) Z_STRLEN_P(zversion));
590+
}
591+
zval_ptr_dtor (&zcookie);
592+
zval_ptr_dtor (&zversion);
593+
return retval;
594+
}
522595

523596

524597
// libevent callbacks
@@ -531,8 +604,6 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
531604
php_memc_client_t *client = (php_memc_client_t *) arg;
532605
memcached_protocol_event_t events;
533606

534-
fprintf (stderr, "memcached event\n");
535-
536607
if (!client->on_connect_invoked) {
537608
if (MEMC_HAS_CB(MEMC_SERVER_ON_CONNECT)) {
538609
zval *zremoteip, *zremoteport;
@@ -572,9 +643,7 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
572643
client->on_connect_invoked = 1;
573644
}
574645

575-
fprintf (stderr, "memcached start work\n");
576646
events = memcached_protocol_client_work (client->protocol_client);
577-
fprintf (stderr, "memcached done work\n");
578647

579648
if (events & MEMCACHED_PROTOCOL_ERROR_EVENT) {
580649
memcached_protocol_client_destroy (client->protocol_client);
@@ -595,8 +664,6 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
595664
if (rc != 0) {
596665
php_error_docref (NULL TSRMLS_CC, E_WARNING, "Failed to schedule events");
597666
}
598-
599-
fprintf (stderr, "memcached event done\n");
600667
}
601668

602669
static
@@ -624,8 +691,6 @@ void s_accept_cb (evutil_socket_t fd, short what, void *arg)
624691
client->event_base = handler->event_base;
625692
client->on_connect_invoked = 0;
626693

627-
memcached_protocol_client_set_verbose (client->protocol_client, 1);
628-
629694
if (!client->protocol_client) {
630695
php_error_docref (NULL TSRMLS_CC, E_WARNING, "Failed to allocate protocol client");
631696
efree (client);
@@ -635,7 +700,6 @@ void s_accept_cb (evutil_socket_t fd, short what, void *arg)
635700

636701
// TODO: this should timeout
637702
rc = event_base_once (handler->event_base, sock, EV_READ, s_handle_memcached_event, client, NULL);
638-
fprintf (stderr, "scheduling\n");
639703

640704
if (rc != 0) {
641705
php_error_docref (NULL TSRMLS_CC, E_WARNING, "Failed to add event for client");
@@ -666,14 +730,10 @@ php_memc_proto_handler_t *php_memc_proto_handler_new ()
666730
handler->callbacks.interface.v1.noop = s_noop_handler;
667731
handler->callbacks.interface.v1.prepend = s_prepend_handler;
668732
handler->callbacks.interface.v1.quit = s_quit_handler;
669-
670733
handler->callbacks.interface.v1.replace = s_replace_handler;
671734
handler->callbacks.interface.v1.set = s_set_handler;
672-
673-
/*
674735
handler->callbacks.interface.v1.stat = s_stat_handler;
675736
handler->callbacks.interface.v1.version = s_version_handler;
676-
*/
677737

678738
memcached_binary_protocol_set_callbacks(handler->protocol_handle, &handler->callbacks);
679739
return handler;
@@ -690,41 +750,83 @@ evutil_socket_t s_create_listening_socket (const char *spec)
690750

691751
addr_len = sizeof (struct sockaddr);
692752
rc = evutil_parse_sockaddr_port (spec, (struct sockaddr *) &addr, &addr_len);
693-
assert (rc == 0);
753+
if (rc != 0) {
754+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse bind address");
755+
return -1;
756+
}
694757

695758
sock = socket (AF_INET, SOCK_STREAM, 0);
696-
assert (sock >= 0);
759+
if (sock < 0) {
760+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "socket failed: %s", strerror (errno));
761+
return -1;
762+
}
697763

698764
rc = bind (sock, (struct sockaddr *) &addr, addr_len);
699-
assert (sock >= 0);
765+
if (rc < 0) {
766+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "bind failed: %s", strerror (errno));
767+
return -1;
768+
}
700769

701770
rc = listen (sock, 1024);
702-
assert (rc >= 0);
771+
if (rc < 0) {
772+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "listen failed: %s", strerror (errno));
773+
return -1;
774+
}
703775

704776
rc = evutil_make_socket_nonblocking (sock);
705-
assert (rc == 0);
777+
if (rc != 0) {
778+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to make socket non-blocking: %s", strerror (errno));
779+
return -1;
780+
}
706781

707782
rc = evutil_make_listen_socket_reuseable (sock);
708-
assert (rc == 0);
783+
if (rc != 0) {
784+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to make socket reuseable: %s", strerror (errno));
785+
return -1;
786+
}
709787

710788
rc = evutil_make_socket_closeonexec (sock);
711-
assert (rc == 0);
712-
789+
if (rc != 0) {
790+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to make socket closeonexec: %s", strerror (errno));
791+
return -1;
792+
}
713793
return sock;
714794
}
715795

716-
void php_memc_proto_handler_run (php_memc_proto_handler_t *handler, const char *address)
796+
zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *handler, const char *address)
717797
{
718798
struct event *accept_event;
719799
evutil_socket_t sock = s_create_listening_socket (address);
720800

721-
handler->event_base = event_base_new();
801+
if (sock == -1) {
802+
return 0;
803+
}
722804

805+
handler->event_base = event_base_new();
806+
if (!handler->event_base) {
807+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "failed to allocate memory: %s", strerror (errno));
808+
}
723809
accept_event = event_new (handler->event_base, sock, EV_READ | EV_PERSIST, s_accept_cb, handler);
810+
if (!accept_event) {
811+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "failed to allocate memory: %s", strerror (errno));
812+
}
724813
event_add (accept_event, NULL);
725814

726-
int f = event_base_dispatch (handler->event_base);
727-
fprintf (stderr, "Re: %d\n", f);
815+
switch (event_base_dispatch (handler->event_base)) {
816+
case -1:
817+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "event_base_dispatch() failed: %s", strerror (errno));
818+
return 0;
819+
break;
820+
821+
case 1:
822+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "no events registered");
823+
return 0;
824+
break;
825+
826+
default:
827+
return 1;
828+
break;
829+
}
728830
}
729831

730832
void php_memc_proto_handler_destroy (php_memc_proto_handler_t **ptr)

Diff for: php_memcached_server.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ php_memc_proto_handler_t *php_memc_proto_handler_new ();
3131

3232
void php_memc_proto_handler_destroy (php_memc_proto_handler_t **ptr);
3333

34-
void php_memc_proto_handler_run (php_memc_proto_handler_t *h, const char *address);
34+
zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *h, const char *address);
3535

3636

3737
#endif

Diff for: server-example/run-server.php

+7
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ function ($client_id, $key, $value, $flags, $expiration, $cas, &$result_cas) {
7676
return Memcached::RESPONSE_SUCCESS;
7777
});
7878

79+
$server->on (Memcached::ON_STAT,
80+
function ($client_id, $key, &$value) {
81+
echo "client_id=[$client_id]: Stat key=[$key]" . PHP_EOL;
82+
$value = "Stat reply";
83+
return Memcached::RESPONSE_SUCCESS;
84+
});
85+
7986
$server->on (Memcached::ON_QUIT,
8087
function ($client_id) {
8188
echo "client_id=[$client_id]: Client quit" . PHP_EOL;

Diff for: server-example/test-server.php

+2
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@
2020
$cache->set ('set_key', 'value 1', 100);
2121
$cache->replace ('replace_key', 'value 2', 200);
2222

23+
$cache->getStats ();
24+
2325
$cache->quit();
2426
sleep (1);

0 commit comments

Comments
 (0)