@@ -149,7 +149,14 @@ static SimulationTime _timer_timespecToSimTime(const struct timespec* config, gb
149149 /* the time that was passed in represents an emulated time, so we need to adjust */
150150 EmulatedTime emNanoSecs = (EmulatedTime )(config -> tv_sec * SIMTIME_ONE_SECOND );
151151 emNanoSecs += (EmulatedTime ) config -> tv_nsec ;
152- simNanoSecs = EMULATED_TIME_TO_SIMULATED_TIME (emNanoSecs );
152+ /* If the emulated time passed in by the plugin is before the time we use as the
153+ * start of the simulation (i.e., EMULATED_TIME_OFFSET), then we use t=0 as
154+ * a proxy for "some time in the past". */
155+ if (emNanoSecs >= EMULATED_TIME_OFFSET ) {
156+ simNanoSecs = EMULATED_TIME_TO_SIMULATED_TIME (emNanoSecs );
157+ } else {
158+ simNanoSecs = 0 ;
159+ }
153160 } else {
154161 /* the config is a relative time, so we just use simtime directly */
155162 simNanoSecs = (SimulationTime )(config -> tv_sec * SIMTIME_ONE_SECOND );
@@ -210,6 +217,7 @@ static void _timer_scheduleNewExpireEvent(Timer* timer) {
210217 * or disarmed the timer in the meantime. This prevents queueing the task indefinitely. */
211218 delay = MIN (delay , SIMTIME_ONE_SECOND );
212219
220+ debug ("Scheduling timer expiration task for %" G_GUINT64_FORMAT " nanoseconds" , delay );
213221 worker_scheduleTask (task , delay );
214222 task_unref (task );
215223
@@ -223,7 +231,7 @@ static void _timer_expire(Timer* timer, gpointer data) {
223231 /* this is a task callback event */
224232
225233 guint expireID = GPOINTER_TO_UINT (data );
226- debug ("timer fd %i expired ; isClosed=%i expireID=%u minValidExpireID=%u" ,
234+ debug ("timer fd %i expire check ; isClosed=%i expireID=%u minValidExpireID=%u" ,
227235 timer -> super .handle , timer -> isClosed , expireID ,
228236 timer -> minValidExpireID );
229237
@@ -273,10 +281,9 @@ static void _timer_arm(Timer* timer, const struct itimerspec *config, gint flags
273281 SimulationTime now = worker_getCurrentTime ();
274282 if (timer -> nextExpireTime >= now ) {
275283 _timer_scheduleNewExpireEvent (timer );
284+ debug ("timer fd %i armed to expire in %" G_GUINT64_FORMAT " nanos" ,
285+ timer -> super .handle , timer -> nextExpireTime - now );
276286 }
277-
278- debug ("timer fd %i armed to expire in %" G_GUINT64_FORMAT " nanos" ,
279- timer -> super .handle , timer -> nextExpireTime - now );
280287}
281288
282289static gboolean _timer_timeIsValid (const struct timespec * config ) {
@@ -320,6 +327,10 @@ gint timer_setTime(Timer* timer, gint flags,
320327 /* always disarm to invalidate old expire events */
321328 _timer_disarm (timer );
322329
330+ /* settings were modified, reset expire count and readability */
331+ timer -> expireCountSinceLastSet = 0 ;
332+ descriptor_adjustStatus (& (timer -> super ), STATUS_DESCRIPTOR_READABLE , FALSE);
333+
323334 /* now set the new times as requested */
324335 if (new_value -> it_value .tv_sec > 0 || new_value -> it_value .tv_nsec > 0 ) {
325336 /* the man page does not specify what to do if it_value says
@@ -329,10 +340,6 @@ gint timer_setTime(Timer* timer, gint flags,
329340 _timer_arm (timer , new_value , flags );
330341 }
331342
332- /* settings were modified, reset expire count and readability */
333- timer -> expireCountSinceLastSet = 0 ;
334- descriptor_adjustStatus (& (timer -> super ), STATUS_DESCRIPTOR_READABLE , FALSE);
335-
336343 return 0 ;
337344}
338345
0 commit comments