agoo 2.15.7 → 2.15.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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