diff --git a/mio/lib/dns-cli.c b/mio/lib/dns-cli.c index feb2f3d..8af73a8 100644 --- a/mio/lib/dns-cli.c +++ b/mio/lib/dns-cli.c @@ -762,7 +762,7 @@ mio_svc_dnc_t* mio_svc_dnc_start (mio_t* mio, const mio_skad_t* serv_addr, const if (mio_dev_sck_bind(dnc->udp_sck, &bi) <= -1) goto oops; } - MIO_SVC_REGISTER (mio, (mio_svc_t*)dnc); + MIO_SVCL_APPEND_SVC (&mio->actsvc, (mio_svc_t*)dnc); return dnc; oops: @@ -781,7 +781,7 @@ void mio_svc_dnc_stop (mio_svc_dnc_t* dnc) if (dnc->udp_sck) mio_dev_sck_kill (dnc->udp_sck); if (dnc->tcp_sck) mio_dev_sck_kill (dnc->tcp_sck); while (dnc->pending_req) release_dns_msg (dnc, dnc->pending_req); - MIO_SVC_UNREGISTER (mio, dnc); + MIO_SVCL_UNLINK_SVC (dnc); mio_freemem (mio, dnc); } diff --git a/mio/lib/dns.c b/mio/lib/dns.c index 296a670..2abd6d9 100644 --- a/mio/lib/dns.c +++ b/mio/lib/dns.c @@ -322,7 +322,7 @@ static int parse_answer_rr (mio_t* mio, mio_dns_rr_part_t rr_part, mio_oow_t pos if (pi->_rrdptr) { - mx = (mio_dns_brrd_soa_t*)pi->_rrdptr; + mx = (mio_dns_brrd_mx_t*)pi->_rrdptr; pi->_rrdptr += MIO_SIZEOF(*mx); MIO_MEMCPY (&mx->preference, pi->_ptr, 2); pi->_ptr += 2; diff --git a/mio/lib/mio-dns.h b/mio/lib/mio-dns.h index e37aaf6..6871be1 100644 --- a/mio/lib/mio-dns.h +++ b/mio/lib/mio-dns.h @@ -387,9 +387,15 @@ typedef void (*mio_svc_dnc_on_resolve_t) ( mio_oow_t len ); -#define mio_svc_dns_getmio(svc) mio_svc_getmio(svc) -#define mio_svc_dnc_getmio(svc) mio_svc_getmio(svc) -#define mio_svc_dnr_getmio(svc) mio_svc_getmio(svc) +#if defined(MIO_HAVE_INLINE) +static MIO_INLINE mio_t* mio_svc_dns_getmio(mio_svc_dns_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); } +static MIO_INLINE mio_t* mio_svc_dnc_getmio(mio_svc_dnc_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); } +static MIO_INLINE mio_t* mio_svc_dnr_getmio(mio_svc_dnr_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); } +#else +# define mio_svc_dns_getmio(svc) mio_svc_getmio(svc) +# define mio_svc_dnc_getmio(svc) mio_svc_getmio(svc) +# define mio_svc_dnr_getmio(svc) mio_svc_getmio(svc) +#endif enum mio_svc_dnc_send_flag_t { diff --git a/mio/lib/mio.c b/mio/lib/mio.c index 4e4a631..aa7db0d 100644 --- a/mio/lib/mio.c +++ b/mio/lib/mio.c @@ -129,20 +129,25 @@ int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_cmgr_t* cmgr, mio_oow_t tmrcapa) * reallocation fails */ /* +1 required for consistency with put_oocs and put_ooch in fmtout.c */ mio->log.ptr = mio_allocmem(mio, (mio->log.capa + 1) * MIO_SIZEOF(*mio->log.ptr)); - if (!mio->log.ptr) goto oops; + if (MIO_UNLIKELY(!mio->log.ptr)) goto oops; /* inititalize the system-side logging */ - if (mio_sys_init(mio) <= -1) goto oops; + if (MIO_UNLIKELY(mio_sys_init(mio) <= -1)) goto oops; sys_inited = 1; /* initialize the timer object */ if (tmrcapa <= 0) tmrcapa = 1; mio->tmr.jobs = mio_allocmem(mio, tmrcapa * MIO_SIZEOF(mio_tmrjob_t)); - if (!mio->tmr.jobs) goto oops; + if (MIO_UNLIKELY(!mio->tmr.jobs)) goto oops; mio->tmr.capa = tmrcapa; + MIO_DEVL_INIT (&mio->actdev); + MIO_DEVL_INIT (&mio->hltdev); + MIO_DEVL_INIT (&mio->zmbdev); MIO_CWQ_INIT (&mio->cwq); + MIO_SVCL_INIT (&mio->actsvc); + mio_sys_gettime (mio, &mio->init_time); return 0; @@ -159,11 +164,7 @@ oops: void mio_fini (mio_t* mio) { mio_dev_t* dev, * next_dev; - struct - { - mio_dev_t* head; - mio_dev_t* tail; - } diehard; + mio_dev_t diehard; mio_oow_t i; /* clean up free cwq list */ @@ -177,62 +178,65 @@ void mio_fini (mio_t* mio) } } - while (mio->actsvc.head) + while (!MIO_SVCL_IS_EMPTY(&mio->actsvc)) { - if (mio->actsvc.head->stop) + mio_svc_t* svc; + + svc = MIO_SVCL_FIRST_SVC(&mio->actsvc); + if (svc->stop) { /* the stop callback must unregister itself */ - mio->actsvc.head->stop (mio->actsvc.head); + svc->stop (svc); } else { /* unregistration only if no stop callback is designated */ - MIO_SVC_UNREGISTER (mio, mio->actsvc.head); + MIO_SVCL_UNLINK_SVC (svc); } } /* kill all registered devices */ - while (mio->actdev.head) + while (!MIO_DEVL_IS_EMPTY(&mio->actdev)) { - mio_dev_kill (mio->actdev.head); + mio_dev_kill (MIO_DEVL_FIRST_DEV(&mio->actdev)); } /* kill all halted devices */ - while (mio->hltdev.head) + while (!MIO_DEVL_IS_EMPTY(&mio->hltdev)) { - mio_dev_kill (mio->hltdev.head); + mio_dev_kill (MIO_DEVL_FIRST_DEV(&mio->hltdev)); } /* clean up all zombie devices */ - MIO_MEMSET (&diehard, 0, MIO_SIZEOF(diehard)); - for (dev = mio->zmbdev.head; dev; ) + MIO_DEVL_INIT (&diehard); + for (dev = MIO_DEVL_FIRST_DEV(&mio->zmbdev); !MIO_DEVL_IS_NIL_DEV(&mio->zmbdev, dev); ) { kill_and_free_device (dev, 1); - if (mio->zmbdev.head == dev) + if (MIO_DEVL_FIRST_DEV(&mio->zmbdev) == dev) { /* the deive has not been freed. go on to the next one */ next_dev = dev->dev_next; /* remove the device from the zombie device list */ - UNLINK_DEVICE_FROM_LIST (&mio->zmbdev, dev); + MIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~MIO_DEV_CAP_ZOMBIE; /* put it to a private list for aborting */ - APPEND_DEVICE_TO_LIST (&diehard, dev); + MIO_DEVL_APPEND_DEV (&diehard, dev); dev = next_dev; } - else dev = mio->zmbdev.head; + else dev = MIO_DEVL_FIRST_DEV(&mio->zmbdev); } - while (diehard.head) + while (!MIO_DEVL_IS_EMPTY(&diehard)) { /* if the kill method returns failure, it can leak some resource * because the device is freed regardless of the failure when 2 * is given to kill_and_free_device(). */ - dev = diehard.head; + dev = MIO_DEVL_FIRST_DEV(&diehard); MIO_ASSERT (mio, !(dev->dev_cap & (MIO_DEV_CAP_ACTIVE | MIO_DEV_CAP_HALTED | MIO_DEV_CAP_ZOMBIE))); - UNLINK_DEVICE_FROM_LIST (&diehard, dev); + MIO_DEVL_UNLINK_DEV (dev); kill_and_free_device (dev, 2); } @@ -346,7 +350,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int if (dev && (events & MIO_DEV_EVENT_OUT)) { /* write pending requests */ - while (!MIO_WQ_ISEMPTY(&dev->wq)) + while (!MIO_WQ_IS_EMPTY(&dev->wq)) { mio_wq_t* q; const mio_uint8_t* uptr; @@ -408,7 +412,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int { /* drain all pending requests. * callbacks are skipped for drained requests */ - while (!MIO_WQ_ISEMPTY(&dev->wq)) + while (!MIO_WQ_IS_EMPTY(&dev->wq)) { q = MIO_WQ_HEAD(&dev->wq); unlink_wq (mio, q); @@ -421,7 +425,7 @@ static MIO_INLINE void handle_event (mio_t* mio, mio_dev_t* dev, int events, int } } - if (dev && MIO_WQ_ISEMPTY(&dev->wq)) + if (dev && MIO_WQ_IS_EMPTY(&dev->wq)) { /* no pending request to write */ if ((dev->dev_cap & MIO_DEV_CAP_IN_CLOSED) && @@ -574,7 +578,7 @@ int mio_exec (mio_t* mio) int ret = 0; /* execute callbacks for completed write operations */ - while (!MIO_CWQ_ISEMPTY(&mio->cwq)) + while (!MIO_CWQ_IS_EMPTY(&mio->cwq)) { mio_cwq_t* cwq; mio_oow_t cwqfl_index; @@ -602,7 +606,7 @@ int mio_exec (mio_t* mio) * multiplexer. the scheduled jobs can safely destroy the devices */ mio_firetmrjobs (mio, MIO_NULL, MIO_NULL); - if (mio->actdev.head) + if (!MIO_DEVL_IS_EMPTY(&mio->actdev)) { /* wait on the multiplexer only if there is at least 1 active device */ mio_ntime_t tmout; @@ -622,13 +626,13 @@ int mio_exec (mio_t* mio) } /* kill all halted devices */ - while (mio->hltdev.head) + while (!MIO_DEVL_IS_EMPTY(&mio->hltdev)) { - MIO_DEBUG1 (mio, "Killing HALTED device %p\n", mio->hltdev.head); - mio_dev_kill (mio->hltdev.head); + mio_dev_t* dev = MIO_DEVL_FIRST_DEV(&mio->hltdev); + MIO_DEBUG1 (mio, "Killing HALTED device %p\n", dev); + mio_dev_kill (dev); } - MIO_ASSERT (mio, mio->hltdev.tail == MIO_NULL); return ret; } @@ -639,13 +643,13 @@ void mio_stop (mio_t* mio, mio_stopreq_t stopreq) int mio_loop (mio_t* mio) { - if (!mio->actdev.head) return 0; + if (MIO_DEVL_IS_EMPTY(&mio->actdev)) return 0; mio->stopreq = MIO_STOPREQ_NONE; if (mio_prologue(mio) <= -1) return -1; - while (mio->stopreq == MIO_STOPREQ_NONE && mio->actdev.head) + while (mio->stopreq == MIO_STOPREQ_NONE && !MIO_DEVL_IS_EMPTY(&mio->actdev)) { if (mio_exec(mio) <= -1) break; /* you can do other things here */ @@ -702,7 +706,7 @@ mio_dev_t* mio_dev_make (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth, if (mio_dev_watch(dev, MIO_DEV_WATCH_START, 0) <= -1) goto oops_after_make; /* and place the new device object at the back of the active device list */ - APPEND_DEVICE_TO_LIST (&mio->actdev, dev); + MIO_DEVL_APPEND_DEV (&mio->actdev, dev); dev->dev_cap |= MIO_DEV_CAP_ACTIVE; return dev; @@ -753,7 +757,7 @@ static int kill_and_free_device (mio_dev_t* dev, int force) if (!(dev->dev_cap & MIO_DEV_CAP_ZOMBIE)) { - APPEND_DEVICE_TO_LIST (&mio->zmbdev, dev); + MIO_DEVL_APPEND_DEV (&mio->zmbdev, dev); dev->dev_cap |= MIO_DEV_CAP_ZOMBIE; } @@ -764,7 +768,7 @@ free_device: if (dev->dev_cap & MIO_DEV_CAP_ZOMBIE) { /* detach it from the zombie device list */ - UNLINK_DEVICE_FROM_LIST (&mio->zmbdev, dev); + MIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~MIO_DEV_CAP_ZOMBIE; } @@ -822,7 +826,7 @@ void mio_dev_kill (mio_dev_t* dev) if (dev->dev_cap & MIO_DEV_CAP_ZOMBIE) { - MIO_ASSERT (mio, MIO_WQ_ISEMPTY(&dev->wq)); + MIO_ASSERT (mio, MIO_WQ_IS_EMPTY(&dev->wq)); MIO_ASSERT (mio, dev->cw_count == 0); MIO_ASSERT (mio, dev->rtmridx == MIO_TMRIDX_INVALID); goto kill_device; @@ -852,7 +856,7 @@ void mio_dev_kill (mio_dev_t* dev) } /* clear pending send requests */ - while (!MIO_WQ_ISEMPTY(&dev->wq)) + while (!MIO_WQ_IS_EMPTY(&dev->wq)) { mio_wq_t* q; q = MIO_WQ_HEAD(&dev->wq); @@ -864,13 +868,13 @@ void mio_dev_kill (mio_dev_t* dev) { /* this device is in the halted state. * unlink it from the halted device list */ - UNLINK_DEVICE_FROM_LIST (&mio->hltdev, dev); + MIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~MIO_DEV_CAP_HALTED; } else { MIO_ASSERT (mio, dev->dev_cap & MIO_DEV_CAP_ACTIVE); - UNLINK_DEVICE_FROM_LIST (&mio->actdev, dev); + MIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~MIO_DEV_CAP_ACTIVE; } @@ -905,11 +909,11 @@ void mio_dev_halt (mio_dev_t* dev) if (dev->dev_cap & MIO_DEV_CAP_ACTIVE) { /* delink the device object from the active device list */ - UNLINK_DEVICE_FROM_LIST (&mio->actdev, dev); + MIO_DEVL_UNLINK_DEV (dev); dev->dev_cap &= ~MIO_DEV_CAP_ACTIVE; /* place it at the back of the halted device list */ - APPEND_DEVICE_TO_LIST (&mio->hltdev, dev); + MIO_DEVL_APPEND_DEV (&mio->hltdev, dev); dev->dev_cap |= MIO_DEV_CAP_HALTED; } } @@ -956,7 +960,7 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events) * output watching is requested only if there're enqueued * data for writing. */ events = MIO_DEV_EVENT_IN; - if (!MIO_WQ_ISEMPTY(&dev->wq)) events |= MIO_DEV_EVENT_OUT; + if (!MIO_WQ_IS_EMPTY(&dev->wq)) events |= MIO_DEV_EVENT_OUT; /* fall through */ case MIO_DEV_WATCH_UPDATE: /* honor event watching requests as given by the caller */ @@ -1128,7 +1132,7 @@ static int __dev_write (mio_dev_t* dev, const void* data, mio_iolen_t len, const uptr = data; urem = len; - if (!MIO_WQ_ISEMPTY(&dev->wq)) + if (!MIO_WQ_IS_EMPTY(&dev->wq)) { /* the writing queue is not empty. * enqueue this request immediately */ @@ -1315,7 +1319,7 @@ static int __dev_writev (mio_dev_t* dev, mio_iovec_t* iov, mio_iolen_t iovcnt, c len = 0; for (i = 0; i < iovcnt; i++) len += iov[i].iov_len; - if (!MIO_WQ_ISEMPTY(&dev->wq)) + if (!MIO_WQ_IS_EMPTY(&dev->wq)) { /* the writing queue is not empty. * enqueue this request immediately */ diff --git a/mio/lib/mio.h b/mio/lib/mio.h index deafdae..3d08291 100644 --- a/mio/lib/mio.h +++ b/mio/lib/mio.h @@ -229,7 +229,7 @@ struct mio_q_t #define MIO_Q_INIT(q) ((q)->next = (q)->prev = (q)) #define MIO_Q_TAIL(q) ((q)->prev) #define MIO_Q_HEAD(q) ((q)->next) -#define MIO_Q_ISEMPTY(q) (MIO_Q_HEAD(q) == (q)) +#define MIO_Q_IS_EMPTY(q) (MIO_Q_HEAD(q) == (q)) #define MIO_Q_ISNODE(q,x) ((q) != (x)) #define MIO_Q_ISHEAD(q,x) (MIO_Q_HEAD(q) == (x)) #define MIO_Q_ISTAIL(q,x) (MIO_Q_TAIL(q) == (x)) @@ -280,7 +280,7 @@ struct mio_cwq_t #define MIO_CWQ_INIT(cwq) ((cwq)->next = (cwq)->prev = (cwq)) #define MIO_CWQ_TAIL(cwq) ((cwq)->prev) #define MIO_CWQ_HEAD(cwq) ((cwq)->next) -#define MIO_CWQ_ISEMPTY(cwq) (MIO_CWQ_HEAD(cwq) == (cwq)) +#define MIO_CWQ_IS_EMPTY(cwq) (MIO_CWQ_HEAD(cwq) == (cwq)) #define MIO_CWQ_ISNODE(cwq,x) ((cwq) != (x)) #define MIO_CWQ_ISHEAD(cwq,x) (MIO_CWQ_HEAD(cwq) == (x)) #define MIO_CWQ_ISTAIL(cwq,x) (MIO_CWQ_TAIL(cwq) == (x)) @@ -311,7 +311,7 @@ struct mio_wq_t #define MIO_WQ_INIT(wq) ((wq)->next = (wq)->prev = (wq)) #define MIO_WQ_TAIL(wq) ((wq)->prev) #define MIO_WQ_HEAD(wq) ((wq)->next) -#define MIO_WQ_ISEMPTY(wq) (MIO_WQ_HEAD(wq) == (wq)) +#define MIO_WQ_IS_EMPTY(wq) (MIO_WQ_HEAD(wq) == (wq)) #define MIO_WQ_ISNODE(wq,x) ((wq) != (x)) #define MIO_WQ_ISHEAD(wq,x) (MIO_WQ_HEAD(wq) == (x)) #define MIO_WQ_ISTAIL(wq,x) (MIO_WQ_TAIL(wq) == (x)) @@ -341,6 +341,32 @@ struct mio_dev_t MIO_DEV_HEADERS; }; +#define MIO_DEVL_PREPEND_DEV(lh,dev) do { \ + (dev)->dev_prev = (lh); \ + (dev)->dev_next = (lh)->dev_next; \ + (dev)->dev_next->dev_prev = (dev); \ + (lh)->dev_next = (dev); \ +} while(0) + +#define MIO_DEVL_APPEND_DEV(lh,dev) do { \ + (dev)->dev_next = (lh); \ + (dev)->dev_prev = (lh)->dev_prev; \ + (dev)->dev_prev->dev_next = (dev); \ + (lh)->dev_prev = (dev); \ +} while(0) + +#define MIO_DEVL_UNLINK_DEV(dev) do { \ + (dev)->dev_prev->dev_next = (dev)->dev_next; \ + (dev)->dev_next->dev_prev = (dev)->dev_prev; \ +} while (0) + + +#define MIO_DEVL_INIT(lh) ((lh)->dev_next = (lh)->dev_prev = lh) +#define MIO_DEVL_FIRST_DEV(lh) ((lh)->dev_next) +#define MIO_DEVL_LAST_DEV(lh) ((lh)->dev_prev) +#define MIO_DEVL_IS_EMPTY(lh) (MIO_DEVL_FIRST_DEV(lh) == (lh)) +#define MIO_DEVL_IS_NIL_DEV(lh,dev) ((dev) == (lh)) + enum mio_dev_cap_t { MIO_DEV_CAP_VIRTUAL = (1 << 0), @@ -405,30 +431,41 @@ typedef void (*mio_svc_stop_t) (mio_svc_t* svc); mio_svc_t* svc_next /* the stop callback is called if it's not NULL and the service is still - * alive when mio_close() is reached. it still calls MIO_SVC_UNREGISTER() + * alive when mio_close() is reached. it still calls MIO_SVCL_UNLINK_SVC() * if the stop callback is NULL. The stop callback, if specified, must - * call MIO_SVC_UNREGISTER(). */ + * call MIO_SVCL_UNLINK_SVC(). */ struct mio_svc_t { MIO_SVC_HEADERS; }; -#define MIO_SVC_REGISTER(mio,svc) do { \ - if ((mio)->actsvc.tail) (mio)->actsvc.tail->svc_next = (svc); \ - else (mio)->actsvc.head = (svc); \ - (svc)->svc_prev = (mio)->actsvc.tail; \ - (svc)->svc_next = MIO_NULL; \ - (mio)->actsvc.tail = (svc); \ +#define MIO_SVCL_PREPEND_SVC(lh,svc) do { \ + (svc)->svc_prev = (lh); \ + (svc)->svc_next = (lh)->svc_next; \ + (svc)->svc_next->svc_prev = (svc); \ + (lh)->svc_next = (svc); \ } while(0) -#define MIO_SVC_UNREGISTER(mio,svc) do { \ - if ((svc)->svc_prev) (svc)->svc_prev->svc_next = (svc)->svc_next; \ - else (mio)->actsvc.head = (svc)->svc_next; \ - if ((svc)->svc_next) (svc)->svc_next->svc_prev = (svc)->svc_prev; \ - else (mio)->actsvc.tail = (svc)->svc_prev; \ +#define MIO_SVCL_APPEND_SVC(lh,svc) do { \ + (svc)->svc_next = (lh); \ + (svc)->svc_prev = (lh)->svc_prev; \ + (svc)->svc_prev->svc_next = (svc); \ + (lh)->svc_prev = (svc); \ +} while(0) + +#define MIO_SVCL_UNLINK_SVC(svc) do { \ + (svc)->svc_prev->svc_next = (svc)->svc_next; \ + (svc)->svc_next->svc_prev = (svc)->svc_prev; \ } while (0) + +#define MIO_SVCL_INIT(lh) ((lh)->svc_next = (lh)->svc_prev = lh) +#define MIO_SVCL_FIRST_SVC(lh) ((lh)->svc_next) +#define MIO_SVCL_LAST_SVC(lh) ((lh)->svc_prev) +#define MIO_SVCL_IS_EMPTY(lh) (MIO_SVCL_FIRST_SVC(lh) == (lh)) +#define MIO_SVCL_IS_NIL_SVC(lh,svc) ((svc) == (lh)) + /* ========================================================================= * MIO LOGGING * ========================================================================= */ @@ -562,23 +599,9 @@ struct mio_t mio_stopreq_t stopreq; /* stop request to abort mio_loop() */ - struct - { - mio_dev_t* head; - mio_dev_t* tail; - } actdev; /* active devices */ - - struct - { - mio_dev_t* head; - mio_dev_t* tail; - } hltdev; /* halted devices */ - - struct - { - mio_dev_t* head; - mio_dev_t* tail; - } zmbdev; /* zombie devices */ + mio_dev_t actdev; /* list head of active devices */ + mio_dev_t hltdev; /* list head of halted devices */ + mio_dev_t zmbdev; /* list head of zombie devices */ mio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */ @@ -593,11 +616,7 @@ struct mio_t mio_cwq_t cwq; mio_cwq_t* cwqfl[MIO_CWQFL_SIZE]; /* list of free cwq objects */ - struct - { - mio_svc_t* head; - mio_svc_t* tail; - } actsvc; /* active services */ + mio_svc_t actsvc; /* list head of active services */ /* platform specific fields below */ mio_sys_t* sysdep;