@@ -78,7 +78,7 @@ long s_invoke_php_callback (php_memc_server_cb_t *cb, zval ***params, ssize_t pa
78
78
cb -> fci .retval_ptr_ptr = & retval_ptr ;
79
79
80
80
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" );
82
82
}
83
83
if (retval_ptr ) {
84
84
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
91
91
// memcached protocol callbacks
92
92
static
93
93
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 )
95
95
{
96
96
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 ;
98
98
zval * * params [6 ];
99
99
100
100
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
115
115
MAKE_STD_ZVAL (zexptime );
116
116
ZVAL_LONG (zexptime , exptime );
117
117
118
- MAKE_STD_ZVAL (zcas );
119
- ZVAL_NULL (zcas );
118
+ MAKE_STD_ZVAL (zresult_cas );
119
+ ZVAL_NULL (zresult_cas );
120
120
121
121
params [0 ] = & zcookie ;
122
122
params [1 ] = & zkey ;
123
123
params [2 ] = & zvalue ;
124
124
params [3 ] = & zflags ;
125
125
params [4 ] = & zexptime ;
126
- params [5 ] = & zcas ;
126
+ params [5 ] = & zresult_cas ;
127
127
128
128
retval = s_invoke_php_callback (& MEMC_GET_CB (MEMC_SERVER_ON_ADD ), params , 6 );
129
129
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 );
134
131
135
132
zval_ptr_dtor (& zcookie );
136
133
zval_ptr_dtor (& zkey );
137
134
zval_ptr_dtor (& zvalue );
138
135
zval_ptr_dtor (& zflags );
139
136
zval_ptr_dtor (& zexptime );
140
- zval_ptr_dtor (& zcas );
137
+ zval_ptr_dtor (& zresult_cas );
141
138
142
139
return retval ;
143
140
}
@@ -519,6 +516,82 @@ protocol_binary_response_status s_set_handler (const void *cookie, const void *k
519
516
s_set_replace_handler (MEMC_SERVER_ON_SET , cookie , key , key_len , data , data_len , flags , expiration , cas , result_cas );
520
517
}
521
518
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
+ }
522
595
523
596
524
597
// libevent callbacks
@@ -531,8 +604,6 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
531
604
php_memc_client_t * client = (php_memc_client_t * ) arg ;
532
605
memcached_protocol_event_t events ;
533
606
534
- fprintf (stderr , "memcached event\n" );
535
-
536
607
if (!client -> on_connect_invoked ) {
537
608
if (MEMC_HAS_CB (MEMC_SERVER_ON_CONNECT )) {
538
609
zval * zremoteip , * zremoteport ;
@@ -572,9 +643,7 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
572
643
client -> on_connect_invoked = 1 ;
573
644
}
574
645
575
- fprintf (stderr , "memcached start work\n" );
576
646
events = memcached_protocol_client_work (client -> protocol_client );
577
- fprintf (stderr , "memcached done work\n" );
578
647
579
648
if (events & MEMCACHED_PROTOCOL_ERROR_EVENT ) {
580
649
memcached_protocol_client_destroy (client -> protocol_client );
@@ -595,8 +664,6 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg)
595
664
if (rc != 0 ) {
596
665
php_error_docref (NULL TSRMLS_CC , E_WARNING , "Failed to schedule events" );
597
666
}
598
-
599
- fprintf (stderr , "memcached event done\n" );
600
667
}
601
668
602
669
static
@@ -624,8 +691,6 @@ void s_accept_cb (evutil_socket_t fd, short what, void *arg)
624
691
client -> event_base = handler -> event_base ;
625
692
client -> on_connect_invoked = 0 ;
626
693
627
- memcached_protocol_client_set_verbose (client -> protocol_client , 1 );
628
-
629
694
if (!client -> protocol_client ) {
630
695
php_error_docref (NULL TSRMLS_CC , E_WARNING , "Failed to allocate protocol client" );
631
696
efree (client );
@@ -635,7 +700,6 @@ void s_accept_cb (evutil_socket_t fd, short what, void *arg)
635
700
636
701
// TODO: this should timeout
637
702
rc = event_base_once (handler -> event_base , sock , EV_READ , s_handle_memcached_event , client , NULL );
638
- fprintf (stderr , "scheduling\n" );
639
703
640
704
if (rc != 0 ) {
641
705
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 ()
666
730
handler -> callbacks .interface .v1 .noop = s_noop_handler ;
667
731
handler -> callbacks .interface .v1 .prepend = s_prepend_handler ;
668
732
handler -> callbacks .interface .v1 .quit = s_quit_handler ;
669
-
670
733
handler -> callbacks .interface .v1 .replace = s_replace_handler ;
671
734
handler -> callbacks .interface .v1 .set = s_set_handler ;
672
-
673
- /*
674
735
handler -> callbacks .interface .v1 .stat = s_stat_handler ;
675
736
handler -> callbacks .interface .v1 .version = s_version_handler ;
676
- */
677
737
678
738
memcached_binary_protocol_set_callbacks (handler -> protocol_handle , & handler -> callbacks );
679
739
return handler ;
@@ -690,41 +750,83 @@ evutil_socket_t s_create_listening_socket (const char *spec)
690
750
691
751
addr_len = sizeof (struct sockaddr );
692
752
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
+ }
694
757
695
758
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
+ }
697
763
698
764
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
+ }
700
769
701
770
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
+ }
703
775
704
776
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
+ }
706
781
707
782
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
+ }
709
787
710
788
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
+ }
713
793
return sock ;
714
794
}
715
795
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 )
717
797
{
718
798
struct event * accept_event ;
719
799
evutil_socket_t sock = s_create_listening_socket (address );
720
800
721
- handler -> event_base = event_base_new ();
801
+ if (sock == -1 ) {
802
+ return 0 ;
803
+ }
722
804
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
+ }
723
809
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
+ }
724
813
event_add (accept_event , NULL );
725
814
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
+ }
728
830
}
729
831
730
832
void php_memc_proto_handler_destroy (php_memc_proto_handler_t * * ptr )
0 commit comments