ble_gatt_client
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
io-mainloop.c
Go to the documentation of this file.
1 
11 /*
12  *
13  * BlueZ - Bluetooth protocol stack for Linux
14  *
15  * Copyright (C) 2012-2014 Intel Corporation. All rights reserved.
16  *
17  *
18  * This library is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU Lesser General Public
20  * License as published by the Free Software Foundation; either
21  * version 2.1 of the License, or (at your option) any later version.
22  *
23  * This library is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26  * Lesser General Public License for more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public
29  * License along with this library; if not, write to the Free Software
30  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31  *
32  */
33 
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37 
38 #include <unistd.h>
39 #include <errno.h>
40 #include <sys/socket.h>
41 
42 #include "mainloop.h"
43 #include "util.h"
44 #include "io.h"
45 
49 struct io {
50  int ref_count;
51  int fd;
52  uint32_t events;
56  void *read_data;
59  void *write_data;
63 };
64 
70 static struct io *io_ref(struct io *io)
71 {
72  if (!io)
73  return NULL;
74 
75  __sync_fetch_and_add(&io->ref_count, 1);
76 
77  return io;
78 }
79 
85 static void io_unref(struct io *io)
86 {
87  if (!io)
88  return;
89 
90  if (__sync_sub_and_fetch(&io->ref_count, 1))
91  return;
92 
93  free(io);
94 }
95 
100 static void io_cleanup(void *user_data)
101 {
102  struct io *io = user_data;
103 
104  if (io->write_destroy)
105  io->write_destroy(io->write_data);
106 
107  if (io->read_destroy)
108  io->read_destroy(io->read_data);
109 
110  if (io->disconnect_destroy)
112 
113  if (io->close_on_destroy)
114  close(io->fd);
115 
116  io->fd = -1;
117 }
118 
128 static void io_callback(int fd, uint32_t events, void *user_data)
129 {
130  struct io *io = user_data;
131 
132  io_ref(io);
133 
134  if ((events & (EPOLLRDHUP | EPOLLHUP | EPOLLERR))) {
135  io->read_callback = NULL;
136  io->write_callback = NULL;
137 
138  if (!io->disconnect_callback) {
139  mainloop_remove_fd(io->fd);
140  io_unref(io);
141  return;
142  }
143 
144  if (!io->disconnect_callback(io, io->disconnect_data)) {
145  if (io->disconnect_destroy)
147 
148  io->disconnect_callback = NULL;
149  io->disconnect_destroy = NULL;
150  io->disconnect_data = NULL;
151 
152  io->events &= ~EPOLLRDHUP;
153 
154  mainloop_modify_fd(io->fd, io->events);
155  }
156  }
157 
158  if ((events & EPOLLIN) && io->read_callback) {
159  if (!io->read_callback(io, io->read_data)) {
160  if (io->read_destroy)
161  io->read_destroy(io->read_data);
162 
163  io->read_callback = NULL;
164  io->read_destroy = NULL;
165  io->read_data = NULL;
166 
167  io->events &= ~EPOLLIN;
168 
169  mainloop_modify_fd(io->fd, io->events);
170  }
171  }
172 
173  if ((events & EPOLLOUT) && io->write_callback) {
174  if (!io->write_callback(io, io->write_data)) {
175  if (io->write_destroy)
176  io->write_destroy(io->write_data);
177 
178  io->write_callback = NULL;
179  io->write_destroy = NULL;
180  io->write_data = NULL;
181 
182  io->events &= ~EPOLLOUT;
183 
184  mainloop_modify_fd(io->fd, io->events);
185  }
186  }
187 
188  io_unref(io);
189 }
190 
197 struct io *io_new(int fd)
198 {
199  struct io *io;
200 
201  if (fd < 0)
202  return NULL;
203 
204  io = new0(struct io, 1);
205  if (!io)
206  return NULL;
207 
208  io->fd = fd;
209  io->events = 0;
210  io->close_on_destroy = false;
211 
212  if (mainloop_add_fd(io->fd, io->events, io_callback,
213  io, io_cleanup) < 0) {
214  free(io);
215  return NULL;
216  }
217 
218  return io_ref(io);
219 }
220 
226 void io_destroy(struct io *io)
227 {
228  if (!io)
229  return;
230 
231  io->read_callback = NULL;
232  io->write_callback = NULL;
233  io->disconnect_callback = NULL;
234 
235  mainloop_remove_fd(io->fd);
236 
237  io_unref(io);
238 }
239 
246 int io_get_fd(struct io *io)
247 {
248  if (!io)
249  return -ENOTCONN;
250 
251  return io->fd;
252 }
253 
260 bool io_set_close_on_destroy(struct io *io, bool do_close)
261 {
262  if (!io)
263  return false;
264 
265  io->close_on_destroy = do_close;
266 
267  return true;
268 }
269 
279  void *user_data, io_destroy_func_t destroy)
280 {
281  uint32_t events;
282 
283  if (!io || io->fd < 0)
284  return false;
285 
286  if (io->read_destroy)
287  io->read_destroy(io->read_data);
288 
289  if (callback)
290  events = io->events | EPOLLIN;
291  else
292  events = io->events & ~EPOLLIN;
293 
294  io->read_callback = callback;
295  io->read_destroy = destroy;
296  io->read_data = user_data;
297 
298  if (events == io->events)
299  return true;
300 
301  if (mainloop_modify_fd(io->fd, events) < 0)
302  return false;
303 
304  io->events = events;
305 
306  return true;
307 }
308 
318  void *user_data, io_destroy_func_t destroy)
319 {
320  uint32_t events;
321 
322  if (!io || io->fd < 0)
323  return false;
324 
325  if (io->write_destroy)
326  io->write_destroy(io->write_data);
327 
328  if (callback)
329  events = io->events | EPOLLOUT;
330  else
331  events = io->events & ~EPOLLOUT;
332 
333  io->write_callback = callback;
334  io->write_destroy = destroy;
335  io->write_data = user_data;
336 
337  if (events == io->events)
338  return true;
339 
340  if (mainloop_modify_fd(io->fd, events) < 0)
341  return false;
342 
343  io->events = events;
344 
345  return true;
346 }
347 
357  void *user_data, io_destroy_func_t destroy)
358 {
359  uint32_t events;
360 
361  if (!io || io->fd < 0)
362  return false;
363 
364  if (io->disconnect_destroy)
366 
367  if (callback)
368  events = io->events | EPOLLRDHUP;
369  else
370  events = io->events & ~EPOLLRDHUP;
371 
372  io->disconnect_callback = callback;
373  io->disconnect_destroy = destroy;
374  io->disconnect_data = user_data;
375 
376  if (events == io->events)
377  return true;
378 
379  if (mainloop_modify_fd(io->fd, events) < 0)
380  return false;
381 
382  io->events = events;
383 
384  return true;
385 }
386 
395 ssize_t io_send(struct io *io, const struct iovec *iov, int iovcnt)
396 {
397  ssize_t ret;
398 
399  if (!io || io->fd < 0)
400  return -ENOTCONN;
401 
402  do {
403  ret = writev(io->fd, iov, iovcnt);
404  } while (ret < 0 && errno == EINTR);
405 
406  if (ret < 0)
407  return -errno;
408 
409  return ret;
410 }
411 
417 bool io_shutdown(struct io *io)
418 {
419  if (!io || io->fd < 0)
420  return false;
421 
422  return shutdown(io->fd, SHUT_RDWR) == 0;
423 }
uint32_t events
Definition: io-mainloop.c:52
bool io_set_write_handler(struct io *io, io_callback_func_t callback, void *user_data, io_destroy_func_t destroy)
Definition: io-mainloop.c:317
bool close_on_destroy
Definition: io-mainloop.c:53
static struct io * io_ref(struct io *io)
Definition: io-mainloop.c:70
struct io * io_new(int fd)
Definition: io-mainloop.c:197
data structure to manage io
Definition: io-mainloop.c:49
ssize_t io_send(struct io *io, const struct iovec *iov, int iovcnt)
Definition: io-mainloop.c:395
io_destroy_func_t write_destroy
Definition: io-mainloop.c:58
bool io_set_close_on_destroy(struct io *io, bool do_close)
Definition: io-mainloop.c:260
void * write_data
Definition: io-mainloop.c:59
io_callback_func_t write_callback
Definition: io-mainloop.c:57
int ref_count
Definition: io-mainloop.c:50
static void io_cleanup(void *user_data)
Definition: io-mainloop.c:100
int mainloop_add_fd(int fd, uint32_t events, mainloop_event_func callback, void *user_data, mainloop_destroy_func destroy)
Definition: mainloop.c:252
int mainloop_remove_fd(int fd)
Definition: mainloop.c:322
bool io_set_disconnect_handler(struct io *io, io_callback_func_t callback, void *user_data, io_destroy_func_t destroy)
Definition: io-mainloop.c:356
static void io_callback(int fd, uint32_t events, void *user_data)
Definition: io-mainloop.c:128
void * read_data
Definition: io-mainloop.c:56
void io_destroy(struct io *io)
Definition: io-mainloop.c:226
void(* io_destroy_func_t)(void *data)
Definition: io.h:27
int mainloop_modify_fd(int fd, uint32_t events)
Definition: mainloop.c:296
io_destroy_func_t read_destroy
Definition: io-mainloop.c:55
bool io_set_read_handler(struct io *io, io_callback_func_t callback, void *user_data, io_destroy_func_t destroy)
Definition: io-mainloop.c:278
int io_get_fd(struct io *io)
Definition: io-mainloop.c:246
io_callback_func_t read_callback
Definition: io-mainloop.c:54
static void io_unref(struct io *io)
Definition: io-mainloop.c:85
void * disconnect_data
Definition: io-mainloop.c:62
bool io_shutdown(struct io *io)
Definition: io-mainloop.c:417
#define new0(t, n)
Definition: util.h:82
bool(* io_callback_func_t)(struct io *io, void *user_data)
Definition: io.h:40
io_destroy_func_t disconnect_destroy
Definition: io-mainloop.c:61
io_callback_func_t disconnect_callback
Definition: io-mainloop.c:60
int fd
Definition: io-mainloop.c:51