summaryrefslogtreecommitdiffstats
path: root/event.h
blob: 24a14082271dea6f29bb64374b93a4ebbf66080f (plain)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2008 Telethra, Inc. <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program (see the file COPYING included with this
 *  distribution); if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef EVENT_H
#define EVENT_H

#include "win32.h"
#include "sig.h"
#include "perf.h"

/*
 * rwflags passed to event_ctl and returned by
 * struct event_set_return.
 */
#define EVENT_UNDEF    4
#define EVENT_READ     (1<<0)
#define EVENT_WRITE    (1<<1)
/*
 * Initialization flags passed to event_set_init
 */
#define EVENT_METHOD_US_TIMEOUT   (1<<0)
#define EVENT_METHOD_FAST         (1<<1)

#ifdef WIN32

typedef const struct rw_handle *event_t;

#define UNDEFINED_EVENT (NULL)

#else

typedef int event_t;

#define UNDEFINED_EVENT (-1)

#endif

struct event_set;
struct event_set_return;

struct event_set_functions
{
  void (*free)(struct event_set *es);
  void (*reset)(struct event_set *es);
  void (*del)(struct event_set *es, event_t event);
  void (*ctl)(struct event_set *es, event_t event, unsigned int rwflags, void *arg);

  /*
   * Return status for wait:
   * -1 on signal or error
   * 0 on timeout
   * length of event_set_return if at least 1 event is returned
   */
  int  (*wait)(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen);
};

struct event_set_return
{
  unsigned int rwflags;
  void *arg;
};

struct event_set
{
  struct event_set_functions func;
};

/*
 * maxevents on input:  desired max number of event_t descriptors
 *                      simultaneously set with event_ctl
 * maxevents on output: may be modified down, depending on limitations
 *                      of underlying API
 * flags:               EVENT_METHOD_x flags
 */
struct event_set *event_set_init (int *maxevents, unsigned int flags);

static inline void
event_free (struct event_set *es)
{
  if (es)
    (*es->func.free)(es);
}

static inline void
event_reset (struct event_set *es)
{
  (*es->func.reset)(es);
}

static inline void
event_del (struct event_set *es, event_t event)
{
  (*es->func.del)(es, event);
}

static inline void
event_ctl (struct event_set *es, event_t event, unsigned int rwflags, void *arg)
{
  (*es->func.ctl)(es, event, rwflags, arg);
}

static inline int
event_wait (struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
{
  int ret;
  perf_push (PERF_IO_WAIT);
  ret = (*es->func.wait)(es, tv, out, outlen);
  perf_pop ();
  return ret;
}

static inline void
event_set_return_init (struct event_set_return *esr)
{
  esr->rwflags = 0;
  esr->arg = NULL;
}

#ifdef WIN32

static inline void
wait_signal (struct event_set *es, void *arg)
{
  if (HANDLE_DEFINED (win32_signal.in.read))
    event_ctl (es, &win32_signal.in, EVENT_READ, arg);
}

#else

static inline void
wait_signal (struct event_set *es, void *arg)
{
}

#endif

#endif