~ubuntu-branches/ubuntu/trusty/geis/trusty

« back to all changes in this revision

Viewing changes to libgeis/geis_timer.c

  • Committer: Package Import Robot
  • Author(s): Chase Douglas
  • Date: 2012-07-30 08:51:42 UTC
  • Revision ID: package-import@ubuntu.com-20120730085142-jrc33ygjvt0ob1wl
Tags: upstream-2.2.11
ImportĀ upstreamĀ versionĀ 2.2.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @file geis_timer.c
 
3
 * @brief Implementation of the GEIS timer module.
 
4
 */
 
5
/* Copyright (C) 2011-2012 Canonical Ltd
 
6
 *
 
7
 * This library is free software: you can redistribute it and/or modify it 
 
8
 * under the terms of the GNU Lesser General Public License version 3
 
9
 * as published by the Free Software Foundation.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful, but 
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranties of 
 
13
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
14
 * PURPOSE.  See the GNU Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public License
 
17
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
#include "geis_config.h"
 
20
#include "geis_timer.h"
 
21
 
 
22
#include <errno.h>
 
23
#include "geis_logging.h"
 
24
#include "geis_private.h"
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
#include <sys/timerfd.h>
 
28
#include <unistd.h>
 
29
 
 
30
static const int nanosecondsPerMillisecond = 1000000;
 
31
/*
 
32
 * The timer object.
 
33
 */
 
34
struct GeisTimer 
 
35
{
 
36
  int                fd;
 
37
  GeisTimerCallback  callback;
 
38
  void              *context;
 
39
};
 
40
 
 
41
 
 
42
/*
 
43
 * Bounces the multiplexor callback into the timer callback.
 
44
 */
 
45
void
 
46
_timer_trampoline(int                             fd GEIS_UNUSED,
 
47
                  GeisBackendMultiplexorActivity  ev GEIS_UNUSED,
 
48
                  void                           *ctx)
 
49
{
 
50
  GeisTimer timer = (GeisTimer)ctx;
 
51
 
 
52
  timer->callback(timer, timer->context);
 
53
}
 
54
 
 
55
 
 
56
/*
 
57
 * Creates a new timer object on a GEIS API instance.
 
58
 */
 
59
GeisTimer
 
60
geis_timer_new(Geis geis, GeisTimerCallback callback, void *context)
 
61
{
 
62
  GeisTimer timer = calloc(1, sizeof(struct GeisTimer));
 
63
  if (!timer)
 
64
  {
 
65
    geis_error("failed to allocate timer structure");
 
66
    goto final_exit;
 
67
  }
 
68
 
 
69
  timer->fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
 
70
  if (timer->fd == -1)
 
71
  {
 
72
    geis_error("error %d creating timerfd: %s", errno, strerror(errno));
 
73
    goto unwind_timer;
 
74
  }
 
75
 
 
76
  timer->callback = callback;
 
77
  timer->context  = context;
 
78
  geis_multiplex_fd(geis, timer->fd, GEIS_BE_MX_READ_AVAILABLE,
 
79
                    _timer_trampoline, timer);
 
80
  goto final_exit;
 
81
 
 
82
unwind_timer:
 
83
  free(timer);
 
84
  timer = 0;
 
85
final_exit:
 
86
  return timer;
 
87
}
 
88
 
 
89
 
 
90
/*
 
91
 * Destroys an existing timer.
 
92
 */
 
93
void
 
94
geis_timer_delete(GeisTimer timer)
 
95
{
 
96
  close(timer->fd);
 
97
  free(timer);
 
98
}
 
99
 
 
100
 
 
101
/*
 
102
 * Cancels an outstanding timer.
 
103
 */
 
104
void
 
105
geis_timer_cancel(GeisTimer timer)
 
106
{
 
107
  struct itimerspec in = { { 0, 0 }, { 0, 0 } };
 
108
  struct itimerspec out;
 
109
  int status = timerfd_settime(timer->fd, 0, &in, &out);
 
110
  if (status != 0)
 
111
  {
 
112
    geis_error("error %d cancelling timerfd: %s", errno, strerror(errno));
 
113
  }
 
114
}
 
115
 
 
116
 
 
117
/*
 
118
 * Starts a timer object a-ticking.
 
119
 */
 
120
void
 
121
geis_timer_start(GeisTimer timer, GeisInteger msec)
 
122
{
 
123
  struct itimerspec in = { { 0, 0 }, { 0, msec * nanosecondsPerMillisecond } };
 
124
  struct itimerspec out;
 
125
  int status = timerfd_settime(timer->fd, 0, &in, &out);
 
126
  if (status != 0)
 
127
  {
 
128
    geis_error("error %d starting timerfd: %s", errno, strerror(errno));
 
129
  }
 
130
}
 
131
 
 
132