| 456 | |
| 457 | |
| 458 | int notify_ebr_subscriptions( ebr_event *ev, evi_params_t *params) |
| 459 | { |
| 460 | ebr_subscription *sub, *sub_next, *sub_prev; |
| 461 | ebr_filter *filter; |
| 462 | ebr_ipc_job *job; |
| 463 | evi_param_t *e_param; |
| 464 | int matches; |
| 465 | struct usr_avp *avps=(void*)-1; |
| 466 | unsigned int my_time; |
| 467 | |
| 468 | LM_DBG("notification received for event %.*s, checking subscriptions\n", |
| 469 | ev->event_name.len, ev->event_name.s); |
| 470 | |
| 471 | my_time = get_ticks(); |
| 472 | |
| 473 | lock_get( &(ev->lock) ); |
| 474 | |
| 475 | ev->last_timeout_check = my_time; |
| 476 | |
| 477 | /* check the EBR subscription on this event and apply the filters */ |
| 478 | sub_prev = NULL; |
| 479 | for ( sub=ev->subs ; sub ; sub_prev=sub, sub=sub_next) { |
| 480 | sub_next = sub->next; |
| 481 | |
| 482 | /* discard expired subscriptions */ |
| 483 | if (sub->expire<my_time) { |
| 484 | LM_DBG("subscription type [%s] from process %d(pid %d) on " |
| 485 | "event <%.*s> expired at %d\n", EBR_SUBS_TYPE(sub), |
| 486 | sub->proc_no, pt[sub->proc_no].pid, |
| 487 | sub->event->event_name.len, sub->event->event_name.s, |
| 488 | sub->expire ); |
| 489 | /* fire the job, if we deal with an WAIT */ |
| 490 | if (sub->flags&EBR_SUBS_TYPE_WAIT) { |
| 491 | job =(ebr_ipc_job*)shm_malloc( sizeof(ebr_ipc_job) ); |
| 492 | if (job==NULL) { |
| 493 | LM_ERR("failed to allocated new IPC job, skipping..\n"); |
| 494 | continue; /* with the next subscription */ |
| 495 | } |
| 496 | job->ev = ev; |
| 497 | job->data = sub->data; |
| 498 | job->flags = sub->flags; |
| 499 | job->tm = sub->tm; |
| 500 | job->avps = NULL; |
| 501 | /* sent the event notification via IPC to resume on the |
| 502 | * subscribing process */ |
| 503 | if (ipc_send_job( sub->proc_no, ebr_ipc_type , (void*)job)<0) { |
| 504 | LM_ERR("failed to send job via IPC, skipping...\n"); |
| 505 | shm_free(job); |
| 506 | continue; /* keep it and try next time */ |
| 507 | } |
| 508 | } else |
| 509 | /* resume if an sync/blocking WAIT */ |
| 510 | if (sub->flags&EBR_SUBS_TYPE_SWAIT) { |
| 511 | struct swait_pack *swait_data = (struct swait_pack*)sub->data; |
| 512 | cond_lock(&swait_data->cond); |
| 513 | cond_signal(&swait_data->cond); |
| 514 | cond_unlock(&swait_data->cond); |
| 515 | /* the "swait_data" will be freed by the waiting proc, |
no test coverage detected