1d413fa5f2916a2a46494edb320340486b262644cDavid 'Digit' Turner#include "android/iolooper.h"
25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* An implementation of iolooper.h based on Unix select() */
55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  include <winsock2.h>
75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  include <sys/types.h>
95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  include <sys/select.h>
105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
11cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "android/sockets.h"
125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct IoLooper {
145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set   reads[1];
155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set   writes[1];
165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set   reads_result[1];
175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set   writes_result[1];
185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int      max_fd;
195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int      max_fd_valid;
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerIoLooper*
235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_new(void)
245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
259a33e8554225c82cd900208f88e8965bb085ab87Vladimir Chtchetkine    IoLooper*  iol = malloc(sizeof(*iol));
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    iolooper_reset(iol);
275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return iol;
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_free( IoLooper*  iol )
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
339a33e8554225c82cd900208f88e8965bb085ab87Vladimir Chtchetkine    free(iol);
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_reset( IoLooper*  iol )
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(iol->reads);
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(iol->writes);
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    iol->max_fd = -1;
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    iol->max_fd_valid = 1;
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_add_fd( IoLooper*  iol, int fd )
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (iol->max_fd_valid && fd > iol->max_fd) {
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iol->max_fd = fd;
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_del_fd( IoLooper*  iol, int fd )
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (iol->max_fd_valid && fd == iol->max_fd)
575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iol->max_fd_valid = 0;
585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
607a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turnervoid
617a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turneriolooper_modify( IoLooper* iol, int fd, int oldflags, int newflags )
627a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner{
637a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner    if (fd < 0)
647a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner        return;
657a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner
667a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner    int changed = oldflags ^ newflags;
677a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner
687a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner    if ((changed & IOLOOPER_READ) != 0) {
697a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner        if ((newflags & IOLOOPER_READ) != 0)
701bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner            iolooper_add_read(iol, fd);
717a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner        else
721bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner            iolooper_del_read(iol, fd);
737a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner    }
747a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner    if ((changed & IOLOOPER_WRITE) != 0) {
757a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner        if ((newflags & IOLOOPER_WRITE) != 0)
761bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner            iolooper_add_write(iol, fd);
777a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner        else
781bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner            iolooper_del_write(iol, fd);
797a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner    }
807a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner}
817a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner
827a17b608de24e3aaf7d5ca030bb80a74dcc3baf9David 'Digit' Turner
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_fd_count( IoLooper*  iol )
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int  max_fd = iol->max_fd;
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int  fd;
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (iol->max_fd_valid)
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return max_fd + 1;
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* recompute max fd */
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (fd = 0; fd < FD_SETSIZE; fd++) {
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!FD_ISSET(fd, iol->reads) && !FD_ISSET(fd, iol->writes))
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        max_fd = fd;
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    iol->max_fd       = max_fd;
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    iol->max_fd_valid = 1;
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return max_fd + 1;
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_add_read( IoLooper*  iol, int  fd )
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (fd >= 0) {
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iolooper_add_fd(iol, fd);
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        FD_SET(fd, iol->reads);
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_add_write( IoLooper*  iol, int  fd )
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (fd >= 0) {
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iolooper_add_fd(iol, fd);
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        FD_SET(fd, iol->writes);
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_del_read( IoLooper*  iol, int  fd )
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (fd >= 0) {
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iolooper_del_fd(iol, fd);
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        FD_CLR(fd, iol->reads);
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_del_write( IoLooper*  iol, int  fd )
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (fd >= 0) {
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iolooper_del_fd(iol, fd);
1379a33e8554225c82cd900208f88e8965bb085ab87Vladimir Chtchetkine        FD_CLR(fd, iol->writes);
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_poll( IoLooper*  iol )
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int     count = iolooper_fd_count(iol);
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int     ret;
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set  errs;
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (count == 0)
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&errs);
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct timeval  tv;
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tv.tv_sec = tv.tv_usec = 0;
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iol->reads_result[0]  = iol->reads[0];
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iol->writes_result[0] = iol->writes[0];
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = select( count, iol->reads_result, iol->writes_result, &errs, &tv);
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while (ret < 0 && errno == EINTR);
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_wait( IoLooper*  iol, int64_t  duration )
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int     count = iolooper_fd_count(iol);
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int     ret;
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd_set  errs;
1739b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner    struct timeval tm0, *tm = NULL;
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (count == 0)
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
17810bc04fd968d7f80258bf1eec665babf28e9e47dVladimir Chtchetkine    CLAMP_MAC_TIMEOUT(duration);
17910bc04fd968d7f80258bf1eec665babf28e9e47dVladimir Chtchetkine
1809b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner    if (duration < 0)
1819b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        tm = NULL;
1829b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner    else {
1839b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        tm = &tm0;
1849b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        tm->tv_sec  = duration / 1000;
1859b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        tm->tv_usec = (duration - 1000*tm->tv_sec) * 1000;
1869b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner    }
1879b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FD_ZERO(&errs);
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iol->reads_result[0]  = iol->reads[0];
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        iol->writes_result[0] = iol->writes[0];
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1949b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        ret = select( count, iol->reads_result, iol->writes_result, &errs, tm);
195d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine        if (ret == 0) {
196d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine            // Indicates timeout
197d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine            errno = ETIMEDOUT;
198d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine        }
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while (ret < 0 && errno == EINTR);
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_is_read( IoLooper*  iol, int  fd )
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return FD_ISSET(fd, iol->reads_result);
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneriolooper_is_write( IoLooper*  iol, int  fd )
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return FD_ISSET(fd, iol->writes_result);
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
216cc19d3eeef59cbd354c1c618f7421d6fe5e0a098Ot ten Thije
217cc19d3eeef59cbd354c1c618f7421d6fe5e0a098Ot ten Thijeint
218cc19d3eeef59cbd354c1c618f7421d6fe5e0a098Ot ten Thijeiolooper_has_operations( IoLooper* iol )
219cc19d3eeef59cbd354c1c618f7421d6fe5e0a098Ot ten Thije{
220cc19d3eeef59cbd354c1c618f7421d6fe5e0a098Ot ten Thije    return iolooper_fd_count(iol) > 0;
221cc19d3eeef59cbd354c1c618f7421d6fe5e0a098Ot ten Thije}
222d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine
223d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkineint64_t
224d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkineiolooper_now(void)
225d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine{
226d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine    struct timeval time_now;
227d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine    return gettimeofday(&time_now, NULL) ? -1 : (int64_t)time_now.tv_sec * 1000LL +
228d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine                                                time_now.tv_usec / 1000;
229d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine}
230d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine
231d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkineint
232d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkineiolooper_wait_absolute(IoLooper* iol, int64_t deadline)
233d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine{
234d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine    int64_t timeout = deadline - iolooper_now();
2351bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner
2361bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner    /* If the deadline has passed, set the timeout to 0, this allows us
2371bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner     * to poll the file descriptor nonetheless */
2381bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner    if (timeout < 0)
2391bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner        timeout = 0;
2401bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner
2411bb627cd086588d3f9650fac04f4034961caf9f1David 'Digit' Turner    return iolooper_wait(iol, timeout);
242d8ba2ae8942abd9757338fc110ce6d215c486b1cVladimir Chtchetkine}
243