blob: 5b7bcfa976ad67044178819b258baabedececb97 [file] [log] [blame]
mlumishb892a272014-12-09 16:28:23 -08001#include "completion_queue.h"
2
3#ifdef HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7#include "php.h"
8#include "php_ini.h"
9#include "ext/standard/info.h"
10#include "ext/spl/spl_exceptions.h"
11#include "php_grpc.h"
12
13#include "zend_exceptions.h"
14
15#include <stdbool.h>
16
17#include "grpc/grpc.h"
18
19#include "event.h"
20#include "timeval.h"
21
22/* Frees and destroys a wrapped instance of grpc_completion_queue */
23void free_wrapped_grpc_completion_queue(void *object TSRMLS_DC){
24 wrapped_grpc_completion_queue *queue = NULL;
25 grpc_event *event;
26 queue = (wrapped_grpc_completion_queue*)object;
27 if(queue->wrapped != NULL){
28 grpc_completion_queue_shutdown(queue->wrapped);
29 event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future);
30 while(event != NULL){
31 if(event->type == GRPC_QUEUE_SHUTDOWN){
32 break;
33 }
34 event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future);
35 }
36 grpc_completion_queue_destroy(queue->wrapped);
37 }
38 efree(queue);
39}
40
41/* Initializes an instance of wrapped_grpc_channel to be associated with an
42 * object of a class specified by class_type */
43zend_object_value create_wrapped_grpc_completion_queue(
44 zend_class_entry *class_type TSRMLS_DC){
45 zend_object_value retval;
46 wrapped_grpc_completion_queue *intern;
47
48 intern = (wrapped_grpc_completion_queue*)emalloc(
49 sizeof(wrapped_grpc_completion_queue));
50 memset(intern, 0, sizeof(wrapped_grpc_completion_queue));
51
52 zend_object_std_init(&intern->std, class_type TSRMLS_CC);
53 object_properties_init(&intern->std, class_type);
54 retval.handle = zend_objects_store_put(
55 intern,
56 (zend_objects_store_dtor_t) zend_objects_destroy_object,
57 free_wrapped_grpc_completion_queue,
58 NULL TSRMLS_CC);
59 retval.handlers = zend_get_std_object_handlers();
60 return retval;
61}
62
63/**
64 * Construct an instance of CompletionQueue
65 */
66PHP_METHOD(CompletionQueue, __construct){
67 wrapped_grpc_completion_queue *queue =
68 (wrapped_grpc_completion_queue*)zend_object_store_get_object(
69 getThis() TSRMLS_CC);
70 queue->wrapped = grpc_completion_queue_create();
71}
72
73/**
74 * Blocks until an event is available, the completion queue is being shutdown,
75 * or timeout is reached. Returns NULL on timeout, otherwise the event that
76 * occurred. Callers should call event.finish once they have processed the
77 * event.
78 * @param Timeval $timeout The timeout for the event
79 * @return Event The event that occurred
80 */
81PHP_METHOD(CompletionQueue, next){
82 zval *timeout;
83 /* "O" == 1 Object */
84 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
85 "O",
86 &timeout, grpc_ce_timeval)==FAILURE){
87 zend_throw_exception(spl_ce_InvalidArgumentException,
88 "next needs a Timeval",
89 1 TSRMLS_CC);
90 return;
91 }
92 wrapped_grpc_completion_queue *completion_queue =
93 (wrapped_grpc_completion_queue*)zend_object_store_get_object(
94 getThis() TSRMLS_CC);
95 wrapped_grpc_timeval *wrapped_timeout =
96 (wrapped_grpc_timeval*)zend_object_store_get_object(timeout TSRMLS_CC);
97 grpc_event *event = grpc_completion_queue_next(completion_queue->wrapped,
98 wrapped_timeout->wrapped);
99 if(event == NULL){
100 RETURN_NULL();
101 }
102 zval *wrapped_event = grpc_php_wrap_event(event);
103 RETURN_DESTROY_ZVAL(wrapped_event);
104}
105
106PHP_METHOD(CompletionQueue, pluck){
107 long tag;
108 zval *timeout;
109 /* "lO" == 1 long, 1 Object */
110 if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
111 "lO",
112 &tag,
113 &timeout, grpc_ce_timeval)==FAILURE){
114 zend_throw_exception(spl_ce_InvalidArgumentException,
115 "pluck needs a long and a Timeval",
116 1 TSRMLS_CC);
117 }
118 wrapped_grpc_completion_queue *completion_queue =
119 (wrapped_grpc_completion_queue*)zend_object_store_get_object(
120 getThis() TSRMLS_CC);
121 wrapped_grpc_timeval *wrapped_timeout =
122 (wrapped_grpc_timeval*)zend_object_store_get_object(timeout TSRMLS_CC);
123 grpc_event *event = grpc_completion_queue_pluck(completion_queue->wrapped,
124 (void*)tag,
125 wrapped_timeout->wrapped);
126 if(event == NULL){
127 RETURN_NULL();
128 }
129 zval *wrapped_event = grpc_php_wrap_event(event);
130 RETURN_DESTROY_ZVAL(wrapped_event);
131}
132
133static zend_function_entry completion_queue_methods[] = {
134 PHP_ME(CompletionQueue, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
135 PHP_ME(CompletionQueue, next, NULL, ZEND_ACC_PUBLIC)
136 PHP_ME(CompletionQueue, pluck, NULL, ZEND_ACC_PUBLIC)
137 PHP_FE_END
138};
139
140void grpc_init_completion_queue(TSRMLS_D){
141 zend_class_entry ce;
142 INIT_CLASS_ENTRY(ce, "Grpc\\CompletionQueue", completion_queue_methods);
143 ce.create_object = create_wrapped_grpc_completion_queue;
144 grpc_ce_completion_queue = zend_register_internal_class(&ce TSRMLS_CC);
145}