ioloop.c revision c0435c854a0e7246373b9752d163095cc4fbe985
cd348e325366620fe047edcc849e3c9424828599Peter Bray Copyright (c) 2002 Timo Sirainen
6c8465e3b4611cb632cba9b0572e3e3737c8c341Vladimir Kotal Permission is hereby granted, free of charge, to any person obtaining
983523cf73bc85cce6282cb5aa78b60f6bcd959fLubos Kosco a copy of this software and associated documentation files (the
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray "Software"), to deal in the Software without restriction, including
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray without limitation the rights to use, copy, modify, merge, publish,
c577d2f6c082eaff9af5bc997d12f3d3bcef537cPeter Bray distribute, sublicense, and/or sell copies of the Software, and to
d20bb899e2e6c692130af57903cb0f909e7bec2aGerbrand van Dieijen permit persons to whom the Software is furnished to do so, subject to
983523cf73bc85cce6282cb5aa78b60f6bcd959fLubos Kosco the following conditions:
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray The above copyright notice and this permission notice shall be
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray included in all copies or substantial portions of the Software.
c577d2f6c082eaff9af5bc997d12f3d3bcef537cPeter Bray THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
c577d2f6c082eaff9af5bc997d12f3d3bcef537cPeter Bray CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
d961aa46ea0d50fed47802497e45226b1965b12dVladimir Kotal/* FIXME: inserting io is slow if there's lots of them. I should add a linked
d961aa46ea0d50fed47802497e45226b1965b12dVladimir Kotal list of priorities pointing to first item in the list with the priority. */
6c8465e3b4611cb632cba9b0572e3e3737c8c341Vladimir Kotalstatic void update_highest_fd(struct ioloop *ioloop)
9dc24f2da404ab474e38fc4d428e5717dc9bcee4Vladimir Kotal for (io = ioloop->ios; io != NULL; io = io->next) {
9dc24f2da404ab474e38fc4d428e5717dc9bcee4Vladimir Kotal if (!io->destroyed && io->fd > ioloop->highest_fd) {
56c25decc0427c204cd35856e521ddf28337e75dLubos Koscostatic void io_list_insert(struct ioloop *ioloop, struct io *io)
6c8465e3b4611cb632cba9b0572e3e3737c8c341Vladimir Kotal for (next = ioloop->ios; next != NULL; next = next->next) {
c577d2f6c082eaff9af5bc997d12f3d3bcef537cPeter Braystruct io *io_add(int fd, int condition, IOFunc func, void *data)
425278cfacbc73f1e955ab6016f206fc5ed93ccbVladimir Kotalstruct io *io_add_priority(int fd, int priority, int condition,
6c8465e3b4611cb632cba9b0572e3e3737c8c341Vladimir Kotal io = p_new(current_ioloop->pool, struct io, 1);
fbf97ea1786d1e25add88bbfb91810170473bc9fLubos Kosco io_loop_handle_add(current_ioloop, io->fd, io->condition);
c276b1ec9722ee95a86a4a381b39c5f405fc1cc4Vladimir Kotal i_assert(io->fd <= current_ioloop->highest_fd);
c276b1ec9722ee95a86a4a381b39c5f405fc1cc4Vladimir Kotal /* notify the real I/O handler */
c276b1ec9722ee95a86a4a381b39c5f405fc1cc4Vladimir Kotal io_loop_handle_remove(current_ioloop, io->fd, io->condition);
c276b1ec9722ee95a86a4a381b39c5f405fc1cc4Vladimir Kotal /* check if we removed the highest fd */
5a0ed1213a40c9ab7c990b442b77455ee27bc799Vladimir Kotalvoid io_destroy(struct ioloop *ioloop, struct io *io)
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray /* remove from list */
cd348e325366620fe047edcc849e3c9424828599Peter Braystatic void timeout_list_insert(struct ioloop *ioloop, struct timeout *timeout)
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray for (t = &ioloop->timeouts; *t != NULL; t = &(*t)->next) {
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Brayinline static void
d280c5e286f5b98be13237f52281ae5afdcf51b9Peter Braytimeout_update_next(struct timeout *timeout, struct timeval *tv_now)
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray /* we don't want microsecond accuracy or this function will be
5e6c91d7e77062129cd0b6ac8aaa546dff216419Lubos Kosco called all the time - millisecond is more than enough */
cd348e325366620fe047edcc849e3c9424828599Peter Bray timeout->next_run.tv_usec += (timeout->msecs%1000)*1000;
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Braystruct timeout *timeout_add(int msecs, TimeoutFunc func, void *context)
cd348e325366620fe047edcc849e3c9424828599Peter Bray timeout = p_new(current_ioloop->pool, struct timeout, 1);
cd348e325366620fe047edcc849e3c9424828599Peter Bray timeout_update_next(timeout, current_ioloop->running ?
bc5565fc58603964988b42b6aee40e246f35d94fVladimir Kotalvoid timeout_destroy(struct ioloop *ioloop, struct timeout *timeout)
bc5565fc58603964988b42b6aee40e246f35d94fVladimir Kotal for (t = &ioloop->timeouts; *t != NULL; t = &(*t)->next) {
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Brayint io_loop_get_wait_time(struct timeout *timeout, struct timeval *tv,
d2a02e104622a26dd90fa88f4f17188f2039809fPeter Bray tv->tv_sec = timeout->next_run.tv_sec - tv->tv_sec;
cd348e325366620fe047edcc849e3c9424828599Peter Bray tv->tv_usec = timeout->next_run.tv_usec - tv->tv_usec;
56d93b0c761868f813ac0bc0b5bc21a7a9fefd89Vladimir Kotal if (tv->tv_sec > 0 || (tv->tv_sec == 0 && tv->tv_usec > 0))
2b024356b830395446c55f50f9f724a63612e578Lubos Kosco /* no need to calculate the times again with this timeout */
5762c9f28c2246777be0e9d49cb29d9c0f49146dLubos Koscovoid io_loop_handle_timeouts(struct ioloop *ioloop)
5762c9f28c2246777be0e9d49cb29d9c0f49146dLubos Kosco unsigned int t_id;
d6ee3934a24d8ccc0e4bb478405d8e5f6a35825dLubos Kosco gettimeofday(&ioloop_timeval, &ioloop_timezone);
d6ee3934a24d8ccc0e4bb478405d8e5f6a35825dLubos Kosco if (ioloop->timeouts == NULL || !ioloop->timeouts->run_now)
b17cb0705d90907337b3528aa7b8ed1700806f26Vladimir Kotal for (t = ioloop->timeouts; t != NULL; t = next) {
6c8465e3b4611cb632cba9b0572e3e3737c8c341Vladimir Kotalvoid io_loop_set_running(struct ioloop *ioloop)
6ce0623fa4ef95af9d77700a1c9c19ec1a919326Guillaume Smet /* initialize time */
6ce0623fa4ef95af9d77700a1c9c19ec1a919326Guillaume Smet gettimeofday(&ioloop_timeval, &ioloop_timezone);
d280c5e286f5b98be13237f52281ae5afdcf51b9Peter Bray i_warning("Timeout leak: %p", (void *) to->func);
83439b4ed8fe40097dc3f2c05168d26bd7926159Vladimir Kotal /* ->prev won't work unless loops are destroyed in create order */