diff options
Diffstat (limited to 'src/lib/daemon_get_timeout.c')
-rw-r--r-- | src/lib/daemon_get_timeout.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/src/lib/daemon_get_timeout.c b/src/lib/daemon_get_timeout.c index fa3e39f9..0e39ab4d 100644 --- a/src/lib/daemon_get_timeout.c +++ b/src/lib/daemon_get_timeout.c | |||
@@ -48,7 +48,79 @@ enum MHD_StatusCode | |||
48 | MHD_daemon_get_timeout (struct MHD_Daemon *daemon, | 48 | MHD_daemon_get_timeout (struct MHD_Daemon *daemon, |
49 | MHD_UNSIGNED_LONG_LONG *timeout) | 49 | MHD_UNSIGNED_LONG_LONG *timeout) |
50 | { | 50 | { |
51 | return -1; | 51 | time_t earliest_deadline; |
52 | time_t now; | ||
53 | struct MHD_Connection *pos; | ||
54 | bool have_timeout; | ||
55 | |||
56 | if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model) | ||
57 | { | ||
58 | #ifdef HAVE_MESSAGES | ||
59 | MHD_DLOG (daemon, | ||
60 | MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_TIMEOUT, | ||
61 | _("Illegal call to MHD_get_timeout\n")); | ||
62 | #endif | ||
63 | return MHD_SC_CONFIGURATION_MISSMATCH_FOR_GET_TIMEOUT; | ||
64 | } | ||
65 | |||
66 | if (daemon->data_already_pending) | ||
67 | { | ||
68 | /* Some data already waiting to be processed. */ | ||
69 | *timeout = 0; | ||
70 | return MHD_SC_OK; | ||
71 | } | ||
72 | |||
73 | #ifdef EPOLL_SUPPORT | ||
74 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | ||
75 | ((NULL != daemon->eready_head) | ||
76 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) | ||
77 | || (NULL != daemon->eready_urh_head) | ||
78 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ | ||
79 | ) ) | ||
80 | { | ||
81 | /* Some connection(s) already have some data pending. */ | ||
82 | *timeout = 0; | ||
83 | return MHD_SC_OK; | ||
84 | } | ||
85 | #endif /* EPOLL_SUPPORT */ | ||
86 | |||
87 | have_timeout = false; | ||
88 | earliest_deadline = 0; /* avoid compiler warnings */ | ||
89 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) | ||
90 | { | ||
91 | if (0 != pos->connection_timeout) | ||
92 | { | ||
93 | if ( (! have_timeout) || | ||
94 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) | ||
95 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
96 | have_timeout = true; | ||
97 | } | ||
98 | } | ||
99 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ | ||
100 | pos = daemon->normal_timeout_tail; | ||
101 | if ( (NULL != pos) && | ||
102 | (0 != pos->connection_timeout) ) | ||
103 | { | ||
104 | if ( (! have_timeout) || | ||
105 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) | ||
106 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
107 | have_timeout = true; | ||
108 | } | ||
109 | |||
110 | if (! have_timeout) | ||
111 | return MHD_SC_NO_TIMEOUT; | ||
112 | now = MHD_monotonic_sec_counter(); | ||
113 | if (earliest_deadline < now) | ||
114 | *timeout = 0; | ||
115 | else | ||
116 | { | ||
117 | const time_t second_left = earliest_deadline - now; | ||
118 | if (second_left > ULLONG_MAX / 1000) /* Ignore compiler warning: 'second_left' is always positive. */ | ||
119 | *timeout = ULLONG_MAX; | ||
120 | else | ||
121 | *timeout = 1000LL * second_left; | ||
122 | } | ||
123 | return MHD_SC_OK; | ||
52 | } | 124 | } |
53 | 125 | ||
54 | /* end of daemon_get_timeout.c */ | 126 | /* end of daemon_get_timeout.c */ |