ivi-main-loop
exampleMainLoop.cpp
1 /**
2  * Basic example using the main loop abstraction.
3  * That example creates a pipe where bytes are regularly written and read, using the various kind of event sources available.
4  * An idle event source is also used to be notified whenever nothing has to be done.
5  */
6 
7 #include "ivi-main-loop.h"
8 #include "ivi-main-loop-log.h"
9 
10 #include <sys/socket.h>
11 #include <fcntl.h>
12 #include "unistd.h"
13 
14 void fd_set_non_blocking(int fd)
15 {
16  int flags = fcntl(fd, F_GETFL, 0);
17  fcntl(fd, F_SETFL, flags | O_NONBLOCK);
18 }
19 
20 using namespace ivi;
21 
22 int main(int argc, const char * *argv)
23 {
24  DefaultEventDispatcherType mainLoop;
25 
26  int pipes[2];
27  if (pipe(pipes) != 0) {
28  log_error() << "Can not create pipe";
29  exit(-1);
30  }
31 
32  int &pipeIn = pipes[0];
33  int &pipeOut = pipes[1];
34  fd_set_non_blocking(pipeIn);
35  fd_set_non_blocking(pipeOut);
36 
37  /// Create a timeout which triggers the writing to the pipe
38  DefaultEventDispatcherType::TimeOutEventSourceType timeOutSource(mainLoop, [&]() {
39 
40  char bytes[64] = {};
41  auto n = write(pipeOut, bytes, sizeof(bytes));
42  if ( n == sizeof(bytes)) {
43  log_debug() << "Written " << n << " bytes to pipe";
44  } else {
45  log_error() << "Can not write data to pipe";
46  mainLoop.quit();
47  }
48 
50  }, 1000);
51  timeOutSource.enable();
52 
53  /// Create a timeout which triggers the closing of the pipe
54  DefaultEventDispatcherType::TimeOutEventSourceType timeOutSourceClose(mainLoop, [&]() {
55  log_debug() << "Closing pipe";
56  close(pipeOut);
58  }, 5000);
59  timeOutSourceClose.enable();
60 
61  /// Create a timeout which triggers the writing to the pipe
62  DefaultEventDispatcherType::IdleEventSourceType idleSource(mainLoop, [&]() {
63  static int i = 0;
64  i++;
65  log_debug() << "idle called " << i << " times";
66 
67  usleep(100000);
68 
70  });
71  idleSource.enable();
72 
73  DefaultEventDispatcherType::TimeOutEventSourceType timeOutStopIdle(mainLoop, [&]() {
74  idleSource.disable();
75  log_debug() << "Idle source disabled";
77  }, 2000);
78  timeOutStopIdle.enable();
79 
80  DefaultEventDispatcherType::FileDescriptorWatchEventSourceType pipeInputSource(mainLoop, [&](
82 
83  char bytes[64];
84 
85  auto r = read(pipeIn, bytes, sizeof(bytes));
86  if (r < 0) {
87  log_error() << "Can not read data";
88  mainLoop.quit();
89  } else {
90  log_debug() << "Read " << r << " bytes from pipe";
91  }
92 
94 
96  pipeInputSource.enable();
97 
98  DefaultEventDispatcherType::FileDescriptorWatchEventSourceType hangUpSource(mainLoop, [&](
100  log_debug() << "Hang up detected => exit main loop";
101  mainLoop.quit();
104  hangUpSource.enable();
105 
106  // Run the main loop. The method will return after the quit() method has been called
107  mainLoop.run();
108 
109  log_debug() << "Terminated";
110 
111  return 0;
112 }
Returning that value from a source's callback function causes the source to be disabled.
Returning that value from a source's callback function causes the source to remain enabled...
Some data is available from the channel.
The channel has been close, which means no data can be read from the corresponding file descriptor...