static int child_init(int rank) { char buffer[EV_SCRIPTROUTE_MAX_SOCK]; str sock_name; str event_name; int idx; /* * Only the first process registers the subscribers * * We do this in child init because here we are sure that all * the events were subscribed */ if (rank != 1) return 0; /* init the socket buffer */ sock_name.s = buffer; memcpy(buffer, SCRIPTROUTE_NAME, sizeof(SCRIPTROUTE_NAME) - 1); buffer[sizeof(SCRIPTROUTE_NAME) - 1] = COLON_C; /* subscribe the route events - idx starts at 1 */ for (idx = 1; event_rlist[idx].a && event_rlist[idx].name; idx++) { /* build the socket */ event_name.s = event_rlist[idx].name; event_name.len = strlen(event_rlist[idx].name); /* first check if the event exists */ if (evi_get_id(&event_name) == EVI_ERROR) { LM_ERR("Event %s not registered\n", event_name.s); return -1; } LM_DBG("Registering event %s\n", event_rlist[idx].name); if (sizeof(SCRIPTROUTE_NAME)+event_name.len > EV_SCRIPTROUTE_MAX_SOCK) { LM_ERR("socket name too big %d (max: %d)\n", (int)(sizeof(SCRIPTROUTE_NAME) + event_name.len), EV_SCRIPTROUTE_MAX_SOCK); return -1; } memcpy(buffer + sizeof(SCRIPTROUTE_NAME), event_name.s, event_name.len); sock_name.len = event_name.len + sizeof(SCRIPTROUTE_NAME); /* register the subscriber - does not expire */ if (evi_event_subscribe(event_name, sock_name, 0, 0) < 0) { LM_ERR("cannot subscribe to event %s\n", event_name.s); return -1; } } return 0; }
int init_ebr_event( ebr_event *ev ) { int event_id; str sock; lock_get( &(ev->lock) ); /* already initialized by other process? */ if (ev->event_id>=0) { lock_release( &(ev->lock) ); return 0; } /* do the actual init under lock */ /* get the event id */ if ( (event_id=evi_get_id(&ev->event_name))==EVI_ERROR) { LM_ERR("Event <%.*s> not available\n", ev->event_name.len, ev->event_name.s); goto error; } ev->event_id = event_id; /* register this EBR event as subscriber to EVI */ sock.len = (sizeof(EVI_ROUTING_NAME)-1) + 1 + ev->event_name.len; sock.s = (char*)pkg_malloc( sock.len ); if (sock.s == NULL) { LM_ERR("failed to allocate EBR socket\n"); goto error; } memcpy( sock.s, EVI_ROUTING_NAME, sizeof(EVI_ROUTING_NAME)-1); sock.s[sizeof(EVI_ROUTING_NAME)-1] = TRANSPORT_SEP; memcpy( sock.s+sizeof(EVI_ROUTING_NAME), ev->event_name.s, ev->event_name.len); LM_DBG("registering socket <%.*s> for event <%.*s>/%d\n", sock.len, sock.s, ev->event_name.len, ev->event_name.s, ev->event_id); if (evi_event_subscribe( ev->event_name, sock, 0, 0) < 0) { LM_ERR("cannot subscribe to event %.*s\n", ev->event_name.len, ev->event_name.s); return -1; } lock_release( &(ev->lock) ); return 0; error: lock_release( &(ev->lock) ); ev->event_id = -1; return -1; }
event_id_t evi_publish_event(str event_name) { int idx; if (event_name.len > MAX_EVENT_NAME) { LM_ERR("event name too long [%d>%d]\n", event_name.len, MAX_EVENT_NAME); return EVI_ERROR; } idx = evi_get_id(&event_name); if (idx != EVI_ERROR) { LM_WARN("Event \"%.*s\" was previously published\n", event_name.len, event_name.s); return idx; } /* check if the event was already registered */ if (!events) { /* first event */ events = shm_malloc(max_alloc_events * sizeof(evi_event_t)); if (!events) { LM_ERR("no more shm memory to hold %d events\n", max_alloc_events); return EVI_ERROR; } } else if (events_no == max_alloc_events) { max_alloc_events *= 2; events = shm_realloc(events, max_alloc_events * sizeof(evi_event_t)); if (!events) { LM_ERR("no more shm memory to hold %d events\n", max_alloc_events); return EVI_ERROR; } } events[events_no].lock = lock_alloc(); if (!events[events_no].lock) { LM_ERR("Failed to allocate subscribers lock\n"); return EVI_ERROR; } events[events_no].lock = lock_init(events[events_no].lock); if (!events[events_no].lock) { LM_ERR("Failed to create subscribers lock\n"); return EVI_ERROR; } events[events_no].id = events_no; events[events_no].name.s = event_name.s; events[events_no].name.len = event_name.len; events[events_no].subscribers = NULL; LM_INFO("Registered event <%.*s(%d)>\n", event_name.len, event_name.s, events_no); return events_no++; }
/* returns an event id */ evi_event_p evi_get_event(str *name) { event_id_t id = evi_get_id(name); return id == EVI_ERROR ? NULL : &events[id]; }