agoo 2.15.7 → 2.15.8

Sign up to get free protection for your applications and to get access to all the features.
data/ext/agoo/server.c CHANGED
@@ -26,11 +26,11 @@
26
26
 
27
27
  #include "server.h"
28
28
 
29
- #define LOOP_UP 100
29
+ #define LOOP_UP 100
30
30
 
31
- struct _agooServer agoo_server = {false};
31
+ struct _agooServer agoo_server = {false};
32
32
 
33
- double agoo_io_loop_ratio = 0.5;
33
+ double agoo_io_loop_ratio = 0.5;
34
34
 
35
35
  int
36
36
  agoo_server_setup(agooErr err) {
@@ -41,19 +41,19 @@ agoo_server_setup(agooErr err) {
41
41
  agoo_server.max_push_pending = 32;
42
42
 
43
43
  if (AGOO_ERR_OK != agoo_pages_init(err) ||
44
- AGOO_ERR_OK != agoo_queue_multi_init(err, &agoo_server.con_queue, 1024, false, true) ||
45
- AGOO_ERR_OK != agoo_queue_multi_init(err, &agoo_server.eval_queue, 1024, true, true)) {
46
- return err->code;
44
+ AGOO_ERR_OK != agoo_queue_multi_init(err, &agoo_server.con_queue, 1024, false, true) ||
45
+ AGOO_ERR_OK != agoo_queue_multi_init(err, &agoo_server.eval_queue, 1024, true, true)) {
46
+ return err->code;
47
47
  }
48
- long i;
48
+ long i;
49
49
 
50
50
  agoo_server.loop_max = 4;
51
51
  if (0 < (i = sysconf(_SC_NPROCESSORS_ONLN))) {
52
- i = (int)(i * agoo_io_loop_ratio);
53
- if (1 >= i) {
54
- i = 1;
55
- }
56
- agoo_server.loop_max = (int)i;
52
+ i = (int)(i * agoo_io_loop_ratio);
53
+ if (1 >= i) {
54
+ i = 1;
55
+ }
56
+ agoo_server.loop_max = (int)i;
57
57
  }
58
58
  return AGOO_ERR_OK;
59
59
  }
@@ -61,8 +61,8 @@ agoo_server_setup(agooErr err) {
61
61
  #ifdef HAVE_OPENSSL_SSL_H
62
62
  static int
63
63
  ssl_error(agooErr err, const char *filename, int line) {
64
- char buf[224];
65
- unsigned long e = ERR_get_error();
64
+ char buf[224];
65
+ unsigned long e = ERR_get_error();
66
66
 
67
67
  ERR_error_string_n(e, buf, sizeof(buf));
68
68
 
@@ -76,18 +76,18 @@ agoo_server_ssl_init(agooErr err, const char *cert_pem, const char *key_pem) {
76
76
  SSL_load_error_strings();
77
77
  SSL_library_init();
78
78
  if (NULL == (agoo_server.ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
79
- return ssl_error(err, __FILE__, __LINE__);
79
+ return ssl_error(err, __FILE__, __LINE__);
80
80
  }
81
81
  SSL_CTX_set_ecdh_auto(agoo_server.ssl_ctx, 1);
82
82
 
83
83
  if (!SSL_CTX_use_certificate_file(agoo_server.ssl_ctx, cert_pem, SSL_FILETYPE_PEM)) {
84
- return ssl_error(err, __FILE__, __LINE__);
84
+ return ssl_error(err, __FILE__, __LINE__);
85
85
  }
86
86
  if (!SSL_CTX_use_PrivateKey_file(agoo_server.ssl_ctx, key_pem, SSL_FILETYPE_PEM)) {
87
- return ssl_error(err, __FILE__, __LINE__);
87
+ return ssl_error(err, __FILE__, __LINE__);
88
88
  }
89
89
  if (!SSL_CTX_check_private_key(agoo_server.ssl_ctx)) {
90
- return agoo_err_set(err, AGOO_ERR_TLS, "TLS private key check failed");
90
+ return agoo_err_set(err, AGOO_ERR_TLS, "TLS private key check failed");
91
91
  }
92
92
  #endif
93
93
  return AGOO_ERR_OK;
@@ -95,94 +95,96 @@ agoo_server_ssl_init(agooErr err, const char *cert_pem, const char *key_pem) {
95
95
 
96
96
  static void
97
97
  add_con_loop() {
98
- struct _agooErr err = AGOO_ERR_INIT;
99
- agooConLoop loop = agoo_conloop_create(&err, 0);
98
+ struct _agooErr err = AGOO_ERR_INIT;
99
+ agooConLoop loop = agoo_conloop_create(&err, 0);
100
100
 
101
101
  if (NULL != loop) {
102
- loop->next = agoo_server.con_loops;
103
- agoo_server.con_loops = loop;
104
- agoo_server.loop_cnt++;
102
+ loop->next = agoo_server.con_loops;
103
+ agoo_server.con_loops = loop;
104
+ agoo_server.loop_cnt++;
105
105
  }
106
106
  }
107
107
 
108
108
  static void*
109
109
  listen_loop(void *x) {
110
- int optval = 1;
111
- struct pollfd pa[100];
112
- struct pollfd *p;
113
- struct _agooErr err = AGOO_ERR_INIT;
114
- struct sockaddr_in client_addr;
115
- int client_sock;
116
- int pcnt = 0;
117
- socklen_t alen = 0;
118
- agooCon con;
119
- int i;
120
- uint64_t cnt = 0;
121
- agooBind b;
110
+ int optval = 1;
111
+ struct pollfd pa[100];
112
+ struct pollfd *p;
113
+ struct _agooErr err = AGOO_ERR_INIT;
114
+ struct sockaddr_in client_addr;
115
+ int client_sock;
116
+ int pcnt = 0;
117
+ socklen_t alen = 0;
118
+ agooCon con;
119
+ int i;
120
+ uint64_t cnt = 0;
121
+ agooBind b;
122
122
 
123
123
  for (b = agoo_server.binds, p = pa; NULL != b; b = b->next, p++, pcnt++) {
124
- p->fd = b->fd;
125
- p->events = POLLIN;
126
- p->revents = 0;
124
+ p->fd = b->fd;
125
+ p->events = POLLIN;
126
+ p->revents = 0;
127
127
  }
128
128
  memset(&client_addr, 0, sizeof(client_addr));
129
129
  atomic_fetch_add(&agoo_server.running, 1);
130
130
  while (agoo_server.active) {
131
- if (0 > (i = poll(pa, pcnt, 200))) {
132
- if (EAGAIN == errno) {
133
- continue;
134
- }
135
- agoo_log_cat(&agoo_error_cat, "Server polling error. %s.", strerror(errno));
136
- // Either a signal or something bad like out of memory. Might as well exit.
137
- break;
138
- }
139
- if (0 == i) { // nothing to read
140
- continue;
141
- }
142
- for (b = agoo_server.binds, p = pa; NULL != b; b = b->next, p++) {
143
- if (0 != (p->revents & POLLIN)) {
144
- if (0 > (client_sock = accept(p->fd, (struct sockaddr*)&client_addr, &alen))) {
145
- agoo_log_cat(&agoo_error_cat, "Server with pid %d accept connection failed. %s.", getpid(), strerror(errno));
146
- } else if (NULL == (con = agoo_con_create(&err, client_sock, ++cnt, b))) {
147
- agoo_log_cat(&agoo_error_cat, "Server with pid %d accept connection failed. %s.", getpid(), err.msg);
148
- close(client_sock);
149
- cnt--;
150
- agoo_err_clear(&err);
151
- } else {
152
- int con_cnt;
131
+ if (0 > (i = poll(pa, pcnt, 200))) {
132
+ if (EAGAIN == errno) {
133
+ continue;
134
+ }
135
+ agoo_log_cat(&agoo_error_cat, "Server polling error. %s.", strerror(errno));
136
+ // Either a signal or something bad like out of memory. Might as well exit.
137
+ break;
138
+ }
139
+ if (0 == i) { // nothing to read
140
+ continue;
141
+ }
142
+ for (b = agoo_server.binds, p = pa; NULL != b; b = b->next, p++) {
143
+ if (0 != (p->revents & POLLIN)) {
144
+ if (0 > (client_sock = accept(p->fd, (struct sockaddr*)&client_addr, &alen))) {
145
+ agoo_log_cat(&agoo_error_cat, "Server with pid %d accept connection failed. %s.", getpid(), strerror(errno));
146
+ } else if (NULL == (con = agoo_con_create(&err, client_sock, ++cnt, b))) {
147
+ agoo_log_cat(&agoo_error_cat, "Server with pid %d accept connection failed. %s.", getpid(), err.msg);
148
+ close(client_sock);
149
+ cnt--;
150
+ agoo_err_clear(&err);
151
+ } else {
152
+ int con_cnt;
153
153
  #ifdef OSX_OS
154
- setsockopt(client_sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
154
+ setsockopt(client_sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
155
155
  #endif
156
156
  #ifdef PLATFORM_LINUX
157
- setsockopt(client_sock, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval));
157
+ setsockopt(client_sock, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval));
158
158
  #endif
159
- fcntl(client_sock, F_SETFL, O_NONBLOCK);
160
- //fcntl(client_sock, F_SETFL, FNDELAY);
161
- setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
162
- setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
163
- agoo_log_cat(&agoo_con_cat, "Server with pid %d accepted connection %llu on %s [%d] from %s",
164
- getpid(), (unsigned long long)cnt, b->id, con->sock, con->remote);
165
-
166
- con_cnt = atomic_fetch_add(&agoo_server.con_cnt, 1);
167
- if (agoo_server.loop_max > agoo_server.loop_cnt && agoo_server.loop_cnt * LOOP_UP < con_cnt) {
168
- add_con_loop();
169
- }
170
- agoo_queue_push(&agoo_server.con_queue, (void*)con);
171
- }
172
- }
173
- if (0 != (p->revents & (POLLERR | POLLHUP | POLLNVAL))) {
174
- if (0 != (p->revents & (POLLHUP | POLLNVAL))) {
175
- agoo_log_cat(&agoo_error_cat, "Agoo server with pid %d socket on %s closed.", getpid(), b->id);
176
- } else {
177
- agoo_log_cat(&agoo_error_cat, "Agoo server with pid %d socket on %s error.", getpid(), b->id);
178
- }
179
- agoo_server.active = false;
180
- }
181
- p->revents = 0;
182
- }
159
+ fcntl(client_sock, F_SETFL, O_NONBLOCK);
160
+ //fcntl(client_sock, F_SETFL, FNDELAY);
161
+ setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
162
+ setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
163
+ agoo_log_cat(&agoo_con_cat, "Server with pid %d accepted connection %llu on %s [%d] from %s",
164
+ getpid(), (unsigned long long)cnt, b->id, con->sock, con->remote);
165
+
166
+ con_cnt = atomic_fetch_add(&agoo_server.con_cnt, 1);
167
+ /* TBD
168
+ if (agoo_server.loop_max > agoo_server.loop_cnt && agoo_server.loop_cnt * LOOP_UP < con_cnt) {
169
+ add_con_loop();
170
+ }
171
+ */
172
+ agoo_queue_push(&agoo_server.con_queue, (void*)con);
173
+ }
174
+ }
175
+ if (0 != (p->revents & (POLLERR | POLLHUP | POLLNVAL))) {
176
+ if (0 != (p->revents & (POLLHUP | POLLNVAL))) {
177
+ agoo_log_cat(&agoo_error_cat, "Agoo server with pid %d socket on %s closed.", getpid(), b->id);
178
+ } else {
179
+ agoo_log_cat(&agoo_error_cat, "Agoo server with pid %d socket on %s error.", getpid(), b->id);
180
+ }
181
+ agoo_server.active = false;
182
+ }
183
+ p->revents = 0;
184
+ }
183
185
  }
184
186
  for (b = agoo_server.binds; NULL != b; b = b->next) {
185
- agoo_bind_close(b);
187
+ agoo_bind_close(b);
186
188
  }
187
189
  atomic_fetch_sub(&agoo_server.running, 1);
188
190
 
@@ -191,12 +193,12 @@ listen_loop(void *x) {
191
193
 
192
194
  int
193
195
  agoo_server_start(agooErr err, const char *app_name, const char *version) {
194
- double giveup;
195
- int xcnt = 0;
196
- int stat;
196
+ double giveup;
197
+ int xcnt = 0;
198
+ int stat;
197
199
 
198
200
  if (0 != (stat = pthread_create(&agoo_server.listen_thread, NULL, listen_loop, NULL))) {
199
- return agoo_err_set(err, stat, "Failed to create server listener thread. %s", strerror(stat));
201
+ return agoo_err_set(err, stat, "Failed to create server listener thread. %s", strerror(stat));
200
202
  }
201
203
  xcnt++;
202
204
  agoo_server.con_loops = agoo_conloop_create(err, 0);
@@ -207,36 +209,36 @@ agoo_server_start(agooErr err, const char *app_name, const char *version) {
207
209
  // might as well create the maximum number of con threads as is
208
210
  // reasonable.
209
211
  if (1 >= agoo_server.thread_cnt) {
210
- while (agoo_server.loop_cnt < agoo_server.loop_max) {
211
- add_con_loop();
212
- xcnt++;
213
- }
212
+ while (agoo_server.loop_cnt < agoo_server.loop_max) {
213
+ add_con_loop();
214
+ xcnt++;
215
+ }
214
216
  }
215
217
  giveup = dtime() + 1.0;
216
218
  while (dtime() < giveup) {
217
- if (xcnt <= (long)atomic_load(&agoo_server.running)) {
218
- break;
219
- }
220
- dsleep(0.01);
219
+ if (xcnt <= (long)atomic_load(&agoo_server.running)) {
220
+ break;
221
+ }
222
+ dsleep(0.01);
221
223
  }
222
224
  if (agoo_info_cat.on) {
223
- agooBind b;
225
+ agooBind b;
224
226
 
225
- for (b = agoo_server.binds; NULL != b; b = b->next) {
226
- agoo_log_cat(&agoo_info_cat, "%s %s with pid %d is listening on %s.", app_name, version, getpid(), b->id);
227
- }
227
+ for (b = agoo_server.binds; NULL != b; b = b->next) {
228
+ agoo_log_cat(&agoo_info_cat, "%s %s with pid %d is listening on %s.", app_name, version, getpid(), b->id);
229
+ }
228
230
  }
229
231
  return AGOO_ERR_OK;
230
232
  }
231
233
 
232
234
  int
233
235
  setup_listen(agooErr err) {
234
- agooBind b;
236
+ agooBind b;
235
237
 
236
238
  for (b = agoo_server.binds; NULL != b; b = b->next) {
237
- if (AGOO_ERR_OK != agoo_bind_listen(err, b)) {
238
- return err->code;
239
- }
239
+ if (AGOO_ERR_OK != agoo_bind_listen(err, b)) {
240
+ return err->code;
241
+ }
240
242
  }
241
243
  agoo_server.active = true;
242
244
 
@@ -246,55 +248,55 @@ setup_listen(agooErr err) {
246
248
  void
247
249
  agoo_server_shutdown(const char *app_name, void (*stop)()) {
248
250
  if (agoo_server.inited) {
249
- agooConLoop loop;
250
-
251
- agoo_log_cat(&agoo_info_cat, "%s with pid %d shutting down.", app_name, getpid());
252
- agoo_server.inited = false;
253
- if (agoo_server.active) {
254
- double giveup = dtime() + 1.0;
255
-
256
- agoo_server.active = false;
257
- pthread_detach(agoo_server.listen_thread);
258
- for (loop = agoo_server.con_loops; NULL != loop; loop = loop->next) {
259
- pthread_detach(loop->thread);
260
- }
261
- while (0 < (long)atomic_load(&agoo_server.running)) {
262
- dsleep(0.1);
263
- if (giveup < dtime()) {
264
- break;
265
- }
266
- }
267
- if (NULL != stop) {
268
- stop();
269
- }
270
- while (NULL != agoo_server.hooks) {
271
- agooHook h = agoo_server.hooks;
272
-
273
- agoo_server.hooks = h->next;
274
- agoo_hook_destroy(h);
275
- }
276
- }
277
- while (NULL != agoo_server.binds) {
278
- agooBind b = agoo_server.binds;
279
-
280
- agoo_server.binds = b->next;
281
- agoo_bind_destroy(b);
282
- }
283
- agoo_queue_cleanup(&agoo_server.con_queue);
284
- while (NULL != (loop = agoo_server.con_loops)) {
285
- agoo_server.con_loops = loop->next;
286
- agoo_conloop_destroy(loop);
287
- }
288
- agoo_queue_cleanup(&agoo_server.eval_queue);
289
-
290
- agoo_pages_cleanup();
291
- agoo_http_cleanup();
292
- agoo_domain_cleanup();
251
+ agooConLoop loop;
252
+
253
+ agoo_log_cat(&agoo_info_cat, "%s with pid %d shutting down.", app_name, getpid());
254
+ agoo_server.inited = false;
255
+ if (agoo_server.active) {
256
+ double giveup = dtime() + 1.0;
257
+
258
+ agoo_server.active = false;
259
+ pthread_detach(agoo_server.listen_thread);
260
+ for (loop = agoo_server.con_loops; NULL != loop; loop = loop->next) {
261
+ pthread_detach(loop->thread);
262
+ }
263
+ while (0 < (long)atomic_load(&agoo_server.running)) {
264
+ dsleep(0.1);
265
+ if (giveup < dtime()) {
266
+ break;
267
+ }
268
+ }
269
+ if (NULL != stop) {
270
+ stop();
271
+ }
272
+ while (NULL != agoo_server.hooks) {
273
+ agooHook h = agoo_server.hooks;
274
+
275
+ agoo_server.hooks = h->next;
276
+ agoo_hook_destroy(h);
277
+ }
278
+ }
279
+ while (NULL != agoo_server.binds) {
280
+ agooBind b = agoo_server.binds;
281
+
282
+ agoo_server.binds = b->next;
283
+ agoo_bind_destroy(b);
284
+ }
285
+ agoo_queue_cleanup(&agoo_server.con_queue);
286
+ while (NULL != (loop = agoo_server.con_loops)) {
287
+ agoo_server.con_loops = loop->next;
288
+ agoo_conloop_destroy(loop);
289
+ }
290
+ agoo_queue_cleanup(&agoo_server.eval_queue);
291
+
292
+ agoo_pages_cleanup();
293
+ agoo_http_cleanup();
294
+ agoo_domain_cleanup();
293
295
  #ifdef HAVE_OPENSSL_SSL_H
294
- if (NULL != agoo_server.ssl_ctx) {
295
- SSL_CTX_free(agoo_server.ssl_ctx);
296
- EVP_cleanup();
297
- }
296
+ if (NULL != agoo_server.ssl_ctx) {
297
+ SSL_CTX_free(agoo_server.ssl_ctx);
298
+ EVP_cleanup();
299
+ }
298
300
  #endif
299
301
  }
300
302
  }
@@ -302,30 +304,30 @@ agoo_server_shutdown(const char *app_name, void (*stop)()) {
302
304
  void
303
305
  agoo_server_bind(agooBind b) {
304
306
  // If a bind with the same port already exists, replace it.
305
- agooBind prev = NULL;
306
- agooBind bx = NULL;
307
+ agooBind prev = NULL;
308
+ agooBind bx = NULL;
307
309
 
308
310
  if (NULL == b->read) {
309
- b->read = agoo_con_http_read;
311
+ b->read = agoo_con_http_read;
310
312
  }
311
313
  if (NULL == b->write) {
312
- b->write = agoo_con_http_write;
314
+ b->write = agoo_con_http_write;
313
315
  }
314
316
  if (NULL == b->events) {
315
- b->events = agoo_con_http_events;
317
+ b->events = agoo_con_http_events;
316
318
  }
317
319
  for (bx = agoo_server.binds; NULL != bx; bx = bx->next) {
318
- if (bx->port == b->port) {
319
- b->next = bx->next;
320
- if (NULL == prev) {
321
- agoo_server.binds = b;
322
- } else {
323
- prev->next = b;
324
- }
325
- agoo_bind_destroy(bx);
326
- return;
327
- }
328
- prev = bx;
320
+ if (bx->port == b->port) {
321
+ b->next = bx->next;
322
+ if (NULL == prev) {
323
+ agoo_server.binds = b;
324
+ } else {
325
+ prev->next = b;
326
+ }
327
+ agoo_bind_destroy(bx);
328
+ return;
329
+ }
330
+ prev = bx;
329
331
  }
330
332
  b->next = agoo_server.binds;
331
333
  agoo_server.binds = b;
@@ -335,9 +337,9 @@ void
335
337
  agoo_server_add_upgraded(agooUpgraded up) {
336
338
  pthread_mutex_lock(&agoo_server.up_lock);
337
339
  if (NULL == agoo_server.up_list) {
338
- up->next = NULL;
340
+ up->next = NULL;
339
341
  } else {
340
- agoo_server.up_list->prev = up;
342
+ agoo_server.up_list->prev = up;
341
343
  }
342
344
  up->next = agoo_server.up_list;
343
345
  agoo_server.up_list = up;
@@ -346,41 +348,41 @@ agoo_server_add_upgraded(agooUpgraded up) {
346
348
  }
347
349
 
348
350
  int
349
- agoo_server_add_func_hook(agooErr err,
350
- agooMethod method,
351
- const char *pattern,
352
- void (*func)(agooReq req),
353
- agooQueue queue,
354
- bool quick) {
355
- agooHook h;
356
- agooHook prev = NULL;
357
- agooHook hook = agoo_hook_func_create(method, pattern, func, queue);
351
+ agoo_server_add_func_hook(agooErr err,
352
+ agooMethod method,
353
+ const char *pattern,
354
+ void (*func)(agooReq req),
355
+ agooQueue queue,
356
+ bool quick) {
357
+ agooHook h;
358
+ agooHook prev = NULL;
359
+ agooHook hook = agoo_hook_func_create(method, pattern, func, queue);
358
360
 
359
361
  if (NULL == hook) {
360
- return AGOO_ERR_MEM(err, "HTTP Server Hook");
362
+ return AGOO_ERR_MEM(err, "HTTP Server Hook");
361
363
  }
362
364
  hook->no_queue = quick;
363
365
  for (h = agoo_server.hooks; NULL != h; h = h->next) {
364
- prev = h;
366
+ prev = h;
365
367
  }
366
368
  if (NULL != prev) {
367
- prev->next = hook;
369
+ prev->next = hook;
368
370
  } else {
369
- agoo_server.hooks = hook;
371
+ agoo_server.hooks = hook;
370
372
  }
371
373
  return AGOO_ERR_OK;
372
374
  }
373
375
 
374
376
  void
375
377
  agoo_server_publish(struct _agooPub *pub) {
376
- agooConLoop loop;
378
+ agooConLoop loop;
377
379
 
378
380
  for (loop = agoo_server.con_loops; NULL != loop; loop = loop->next) {
379
- if (NULL == loop->next) {
380
- agoo_queue_push(&loop->pub_queue, pub);
381
- } else {
382
- agoo_queue_push(&loop->pub_queue, agoo_pub_dup(pub));
383
- }
381
+ if (NULL == loop->next) {
382
+ agoo_queue_push(&loop->pub_queue, pub);
383
+ } else {
384
+ agoo_queue_push(&loop->pub_queue, agoo_pub_dup(pub));
385
+ }
384
386
  }
385
387
  }
386
388
 
@@ -394,19 +396,19 @@ agoo_server_add_gsub(gqlSub sub) {
394
396
 
395
397
  void
396
398
  agoo_server_del_gsub(gqlSub sub) {
397
- gqlSub s;
398
- gqlSub prev = NULL;
399
+ gqlSub s;
400
+ gqlSub prev = NULL;
399
401
 
400
402
  pthread_mutex_lock(&agoo_server.up_lock);
401
403
  for (s = agoo_server.gsub_list; NULL != s; s = s->next) {
402
- if (s == sub) {
403
- if (NULL == prev) {
404
- agoo_server.gsub_list = s->next;
405
- } else {
406
- prev->next = s->next;
407
- }
408
- }
409
- prev = s;
404
+ if (s == sub) {
405
+ if (NULL == prev) {
406
+ agoo_server.gsub_list = s->next;
407
+ } else {
408
+ prev->next = s->next;
409
+ }
410
+ }
411
+ prev = s;
410
412
  }
411
413
  pthread_mutex_unlock(&agoo_server.up_lock);
412
414
  }
@@ -414,79 +416,79 @@ agoo_server_del_gsub(gqlSub sub) {
414
416
  static bool
415
417
  subject_check(const char *pattern, const char *subject) {
416
418
  for (; '\0' != *pattern && '\0' != *subject; subject++) {
417
- if (*subject == *pattern) {
418
- pattern++;
419
- } else if ('*' == *pattern) {
420
- for (; '\0' != *subject && '.' != *subject; subject++) {
421
- }
422
- if ('\0' == *subject) {
423
- return true;
424
- }
425
- pattern++;
426
- } else if ('>' == *pattern) {
427
- return true;
428
- } else {
429
- break;
430
- }
419
+ if (*subject == *pattern) {
420
+ pattern++;
421
+ } else if ('*' == *pattern) {
422
+ for (; '\0' != *subject && '.' != *subject; subject++) {
423
+ }
424
+ if ('\0' == *subject) {
425
+ return true;
426
+ }
427
+ pattern++;
428
+ } else if ('>' == *pattern) {
429
+ return true;
430
+ } else {
431
+ break;
432
+ }
431
433
  }
432
434
  return '\0' == *pattern && '\0' == *subject;
433
435
  }
434
436
 
435
437
  static agooText
436
438
  gpub_eval(agooErr err, gqlDoc query, gqlRef event) {
437
- agooText t = NULL;
438
- gqlSel sel;
439
- gqlValue result;
439
+ agooText t = NULL;
440
+ gqlSel sel;
441
+ gqlValue result;
440
442
 
441
443
  if (NULL == query->ops || NULL == query->ops->sels) {
442
- agoo_err_set(err, AGOO_ERR_TYPE, "subscription not valid");
443
- return NULL;
444
+ agoo_err_set(err, AGOO_ERR_TYPE, "subscription not valid");
445
+ return NULL;
444
446
  }
445
447
  sel = query->ops->sels;
446
448
  if (NULL != (result = gql_object_create(err))) {
447
- struct _gqlField field;
448
-
449
- memset(&field, 0, sizeof(field));
450
- field.type = sel->type;
451
- if (AGOO_ERR_OK != gql_eval_sels(err, query, event, &field, sel->sels, result, 0)) {
452
- gql_value_destroy(result);
453
- return NULL;
454
- }
455
- if (NULL == (t = agoo_text_allocate(1024))) {
456
- AGOO_ERR_MEM(err, "Text");
457
- return NULL;
458
- }
459
- t = gql_value_json(t, result, 0, 0);
460
- gql_value_destroy(result);
449
+ struct _gqlField field;
450
+
451
+ memset(&field, 0, sizeof(field));
452
+ field.type = sel->type;
453
+ if (AGOO_ERR_OK != gql_eval_sels(err, query, event, &field, sel->sels, result, 0)) {
454
+ gql_value_destroy(result);
455
+ return NULL;
456
+ }
457
+ if (NULL == (t = agoo_text_allocate(1024))) {
458
+ AGOO_ERR_MEM(err, "Text");
459
+ return NULL;
460
+ }
461
+ t = gql_value_json(t, result, 0, 0);
462
+ gql_value_destroy(result);
461
463
  }
462
464
  return t;
463
465
  }
464
466
 
465
467
  int
466
468
  agoo_server_gpublish(agooErr err, const char *subject, gqlRef event) {
467
- gqlSub sub;
468
- gqlType type;
469
+ gqlSub sub;
470
+ gqlType type;
469
471
 
470
472
  if (NULL == gql_type_func || NULL == (type = gql_type_func(event))) {
471
- return agoo_err_set(err, AGOO_ERR_TYPE, "Not able to determine the type for a GraphQL publish.");
473
+ return agoo_err_set(err, AGOO_ERR_TYPE, "Not able to determine the type for a GraphQL publish.");
472
474
  }
473
475
  pthread_mutex_lock(&agoo_server.up_lock);
474
476
  for (sub = agoo_server.gsub_list; NULL != sub; sub = sub->next) {
475
- if (subject_check(sub->subject, subject)) {
476
- agooRes res;
477
- agooText t;
478
-
479
- if (NULL == (res = agoo_res_create(sub->con))) {
480
- AGOO_ERR_MEM(err, "Response");
481
- break;
482
- }
483
- if (NULL == (t = gpub_eval(err, sub->query, event))) {
484
- break;
485
- }
486
- res->con_kind = AGOO_CON_ANY;
487
- agoo_res_message_push(res, t);
488
- agoo_con_res_append(sub->con, res);
489
- }
477
+ if (subject_check(sub->subject, subject)) {
478
+ agooRes res;
479
+ agooText t;
480
+
481
+ if (NULL == (res = agoo_res_create(sub->con))) {
482
+ AGOO_ERR_MEM(err, "Response");
483
+ break;
484
+ }
485
+ if (NULL == (t = gpub_eval(err, sub->query, event))) {
486
+ break;
487
+ }
488
+ res->con_kind = AGOO_CON_ANY;
489
+ agoo_res_message_push(res, t);
490
+ agoo_con_res_append(sub->con, res);
491
+ }
490
492
  }
491
493
  pthread_mutex_unlock(&agoo_server.up_lock);
492
494