| 483 | } |
| 484 | |
| 485 | int evs_sub(fs_evs *sock, const str *tag, const str_list *name, |
| 486 | ipc_handler_type ipc_type) |
| 487 | { |
| 488 | struct fs_event *event; |
| 489 | int ret = 0; |
| 490 | |
| 491 | lock_start_write(sock->lists_lk); |
| 492 | |
| 493 | for (; name; name = name->next) { |
| 494 | event = NULL; |
| 495 | |
| 496 | event = get_event(sock, &name->s); |
| 497 | if (!event) { |
| 498 | event = add_event(sock, &name->s); |
| 499 | if (!event) { |
| 500 | LM_ERR("failed to alloc event\n"); |
| 501 | ret = -1; |
| 502 | continue; |
| 503 | } |
| 504 | } |
| 505 | |
| 506 | if (add_event_subscription(event, tag, ipc_type) != 0) { |
| 507 | LM_ERR("failed to alloc subscription\n"); |
| 508 | ret = -1; |
| 509 | continue; |
| 510 | } |
| 511 | |
| 512 | if (event->refsum == 1) { |
| 513 | /* there is a pending unsub action we must cancel! */ |
| 514 | if (event->action == FS_EVENT_UNSUB) |
| 515 | event->action = FS_EVENT_NOP; |
| 516 | else |
| 517 | event->action = FS_EVENT_SUB; |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | lock_stop_write(sock->lists_lk); |
| 522 | |
| 523 | /* always place it in the ESL "todo" list; we released the lock, so we |
| 524 | * cannot guarantee that the above esl_cmd's haven't been consumed by now |
| 525 | * worst case: we mark it as "todo" with no pending cmds, which is fine */ |
| 526 | lock_start_write(sockets_esl_lock); |
| 527 | if (list_empty(&sock->esl_cmd_list)) |
| 528 | list_add_tail(&sock->esl_cmd_list, fs_sockets_esl); |
| 529 | lock_stop_write(sockets_esl_lock); |
| 530 | |
| 531 | if (ret != 0) |
| 532 | LM_ERR("oom! some events may have been skipped\n"); |
| 533 | |
| 534 | return ret; |
| 535 | } |
| 536 | |
| 537 | void evs_unsub(fs_evs *sock, const str *tag, const str_list *name) |
| 538 | { |
no test coverage detected