File: timer.c

package info (click to toggle)
seafile 9.0.16-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,072 kB
  • sloc: ansic: 45,052; python: 6,601; sh: 272; makefile: 268; cpp: 93
file content (94 lines) | stat: -rw-r--r-- 2,032 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#include <event2/event.h>
#include <event2/event_compat.h>
#include <event2/event_struct.h>
#else
#include <event.h>
#endif

#ifndef WIN32
#include <sys/time.h>
#endif

#include "seafile-session.h"

#include "utils.h"

#include "timer.h"

struct SeafTimer
{
    struct event   *event;
    struct timeval tv;
    TimerCB        func;
    void          *user_data;
    uint8_t        in_callback;
};

static void
timer_callback (evutil_socket_t fd, short event, void *vtimer)
{
    int more;
    struct SeafTimer *timer = vtimer;

    timer->in_callback = 1;
    more = (*timer->func) (timer->user_data);
    timer->in_callback = 0;

    if (more)
        evtimer_add (timer->event, &timer->tv);
    else
        seaf_timer_free (&timer);
}

void
seaf_timer_free (SeafTimer **ptimer)
{
    SeafTimer *timer;

    /* zero out the argument passed in */
    g_return_if_fail (ptimer);

    timer = *ptimer;
    *ptimer = NULL;

    /* destroy the timer directly or via the command queue */
    if (timer && !timer->in_callback)
    {
        event_del (timer->event);
        event_free (timer->event);
        g_free (timer);
    }
}

struct timeval
timeval_from_msec (uint64_t milliseconds)
{
    struct timeval ret;
    const uint64_t microseconds = milliseconds * 1000;
    ret.tv_sec  = microseconds / 1000000;
    ret.tv_usec = microseconds % 1000000;
    return ret;
}

SeafTimer*
seaf_timer_new (TimerCB         func,
                void           *user_data,
                uint64_t        interval_milliseconds)
{
    SeafTimer *timer = g_new0 (SeafTimer, 1);

    timer->tv = timeval_from_msec (interval_milliseconds);
    timer->func = func;
    timer->user_data = user_data;

    timer->event = evtimer_new (seaf->ev_base, timer_callback, timer);
    if (timer->event == NULL) {
        return NULL;
    }
    evtimer_add (timer->event, &timer->tv);

    return timer;
}