📄 event.c
字号:
/*------------------------------------------------------------------------- * event.c - eventqnext, eventqpost, eventqwant, eventqenqueue, * eventqdequeue, eventqinit, eventqdestroy, eventqclear, eventqfilerssrc, * eventqfilterall *------------------------------------------------------------------------- */#include <event.h>#include <rtp.h>#include <strings.h>#include <stdlib.h>#include <hash.h>#include <semaphore.h>#include <bufpool.h>/*------------------------------------------------------------------------ * eventqnext - wait for next event (if blocking) and copy into buf *------------------------------------------------------------------------ */inteventqnext(struct eventqueue *peq, struct event *buf, int buflen){ struct event *pe; if (peq->eq_eventblock) { if (sem_wait(&peq->eq_eventsem) < 0) return ERROR; } else if (sem_trywait(&peq->eq_eventsem) < 0) return ERROR; pe = eventqdequeue(peq); if (pe == NULL) return ERROR; pe->ev_next = NULL; buflen = min(buflen, pe->ev_datalen + sizeof(struct event)); memcpy(buf, pe, buflen); bufpoolfreebuf(pe); return buflen;}/*------------------------------------------------------------------------ * eventqpost - enqueue an event if appropriate and signal the semaphore *------------------------------------------------------------------------ */inteventqpost(struct eventqueue *peq, int type, ssrc_t ssrc, void *data, int length){ struct event *pe; if (eventqwant(peq, type, ssrc) != TRUE) return OK; pe = (struct event *) bufpoolgetbuf(&peq->eq_bpool); if (pe == NULL) return ERROR; pe->ev_type = type; pe->ev_ssrc = ssrc; clock_gettime(CLOCK_REALTIME, &pe->ev_time); pe->ev_datalen = min(length, peq->eq_bpool.bp_size - sizeof(struct event)); memcpy(pe->ev_data, data, pe->ev_datalen); eventqenqueue(peq, pe); sem_post(&peq->eq_eventsem); return OK;}/*------------------------------------------------------------------------ * eventqwant - determine whether a particular event is wanted by an evntq *------------------------------------------------------------------------ */booleventqwant(struct eventqueue *peq, int type, ssrc_t ssrc){ char *vec; if (type > EVENT_TYPES) return FALSE; /* * Determine if the event is wanted * regardless of SSRC. */ if (BIT_SET(peq->eq_wantall, type) == TRUE) return TRUE; /* * Determine if event is wanted * for the particular source. */ vec = (char *) htget(peq->eq_ssrcs, ssrc); if (vec != NULL) if (BIT_SET(vec, type) == TRUE) return TRUE; return FALSE;}/*------------------------------------------------------------------------ * eventqenqueue - place an event into the eventqueue *------------------------------------------------------------------------ */inteventqenqueue(struct eventqueue *peq, struct event *pe){ if (pthread_mutex_lock(&peq->eq_eventqueuemutex) != 0) return ERROR; if (peq->eq_eventtail == NULL) { pe->ev_next = NULL; peq->eq_eventtail = pe; peq->eq_eventhead = pe; } else { pe->ev_next = NULL; peq->eq_eventtail->ev_next = pe; peq->eq_eventtail = pe; } pthread_mutex_unlock(&peq->eq_eventqueuemutex); return OK;}/*------------------------------------------------------------------------ * eventqdequeue - remove the next event from the event queue *------------------------------------------------------------------------ */struct event *eventqdequeue(struct eventqueue *peq){ struct event *pe; if (pthread_mutex_lock(&peq->eq_eventqueuemutex) != 0) return NULL; if (peq->eq_eventhead == NULL) { pthread_mutex_unlock(&peq->eq_eventqueuemutex); return NULL; } pe = peq->eq_eventhead; peq->eq_eventhead = pe->ev_next; if (peq->eq_eventhead == NULL) peq->eq_eventtail = NULL; pthread_mutex_unlock(&peq->eq_eventqueuemutex); return pe;}/*------------------------------------------------------------------------ * eventqinit - initialize an eventqueue *------------------------------------------------------------------------ */inteventqinit(struct eventqueue *peq, int htsize, bool block, int bpbufsz, int bpbufcnt){ if (pthread_mutex_init(&peq->eq_eventqueuemutex, NULL) < 0) return ERROR; if (sem_init(&peq->eq_eventsem, PTHREAD_PROCESS_PRIVATE, 0) < 0) { pthread_mutex_destroy(&peq->eq_eventqueuemutex); return ERROR; } if (bufpoolinit(&peq->eq_bpool, bpbufsz, bpbufcnt) == ERROR) { sem_destroy(&peq->eq_eventsem); pthread_mutex_destroy(&peq->eq_eventqueuemutex); return ERROR; } peq->eq_ssrcs = htnew(htsize, hashunsignedint, unsignedinteq, NULL, free); memset(peq->eq_wantall, 0, sizeof(peq->eq_wantall)); peq->eq_eventtail = peq->eq_eventhead = NULL; peq->eq_eventblock = block; return OK;}/*------------------------------------------------------------------------ * eventqdestroy - deallocate resources used by an event queue *------------------------------------------------------------------------ */inteventqdestroy(struct eventqueue *peq){ if (pthread_mutex_lock(&peq->eq_eventqueuemutex) != 0) return ERROR; htdestroy(peq->eq_ssrcs); eventqclear(peq); sem_destroy(&peq->eq_eventsem); pthread_mutex_unlock(&peq->eq_eventqueuemutex); pthread_mutex_destroy(&peq->eq_eventqueuemutex); return OK;}/*------------------------------------------------------------------------ * eventqclear - remove all events from an event queue *------------------------------------------------------------------------ */inteventqclear(struct eventqueue *peq){ struct event *pe; while(sem_trywait(&peq->eq_eventsem) == 0) { pe = eventqdequeue(peq); if (pe != NULL) bufpoolfreebuf(pe); } return OK;}/*------------------------------------------------------------------------ * eventqfilterssrc - turn a particular event on or off for a particular * ssrc in a particular event queue *------------------------------------------------------------------------ */inteventqfilterssrc(struct eventqueue *peq, int type, ssrc_t ssrc, bool on){ char *pvec; if (type > EVENT_TYPES) return ERROR; pvec = htget(peq->eq_ssrcs, ssrc); if (pvec == NULL) { pvec = (char *) malloc(EVENT_VECTOR_SZ); if (pvec == NULL) return ERROR; htadd(peq->eq_ssrcs, ssrc, pvec); } if (on == TRUE) SET_BIT(pvec, type); else UNSET_BIT(pvec, type); return OK;}/*------------------------------------------------------------------------ * eventqfilterall - turn an event on or off for *all* ssrcs * Turning an event "off for all" clears the appropriate bit in the * eq_wantall vector; the event will still be received for SSRCs for * which it was turned on with eventfilterssrc(). *------------------------------------------------------------------------ */inteventqfilterall(struct eventqueue *peq, int type, bool on){ if (on == TRUE) SET_BIT(peq->eq_wantall, type); else UNSET_BIT(peq->eq_wantall, type); return OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -