RDK Documentation (Open Sourced RDK Components)
glib_tools.cpp
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2017 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include "glib_tools.h"
21 
22 #include <unistd.h>
23 #include <errno.h>
24 #include <stdio.h>
25 
26 class EventSource {
27 public:
28  static GSourceFuncs sourceFuncs;
29  GSource src;
30  GPollFD pfd;
31  PipeSourceCallback cb;
32  void* ctx;
33 };
34 
35 gboolean g_prepare (GSource*, gint *timeout_)
36 {
37  *timeout_ = -1;
38  return FALSE;
39 }
40 gboolean g_check (GSource *base)
41 {
42  auto* source = reinterpret_cast<EventSource*>(base);
43  return !!source->pfd.revents;
44 }
45 gboolean g_dispatch (GSource *base,
46  GSourceFunc callback,
47  gpointer user_data)
48 {
49  auto* source = reinterpret_cast<EventSource*>(base);
50  if (source->pfd.revents & G_IO_IN)
51  {
52  // read one byte from file
53  // and fire callback
54  // thread will not block here.
55  static char discard[1];
56  int ret = HANDLE_EINTR_EAGAIN(read(source->pfd.fd, discard, 1));
57  if (-1 == ret)
58  perror("unable to read from pipe");
59 
60  source->cb(source->ctx);
61  }
62 
63  if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
64  {
65  // TODO: improve logging?
66  puts("ERROR during read from file descriptor");
67  return FALSE;
68  }
69 
70  source->pfd.revents = 0;
71  return TRUE;
72 }
73 
74 GSourceFuncs EventSource::sourceFuncs =
75 {
76  g_prepare,
77  g_check,
78  g_dispatch,
79  NULL
80 };
81 
82 GSource* pipe_source_new(int pipefd[2], PipeSourceCallback cb, void* ctx)
83 {
84  // create source
85  auto* Esource = (EventSource*)g_source_new(&EventSource::sourceFuncs, sizeof(EventSource));
86 
87  auto* source = (GSource*) Esource;
88 
89  // create pipe
90  int ret = pipe(pipefd);
91  if (ret == -1)
92  perror("can't create pipe");
93 
94  // attach pipe out FD to source
95  Esource->pfd.fd = pipefd[PIPE_LISTEN];
96  Esource->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
97  Esource->pfd.revents = 0;
98  Esource->cb = cb;
99  Esource->ctx = ctx;
100  g_source_add_poll(source, &Esource->pfd);
101 
102  g_source_set_name(source, "rtRemoteSource");
103  g_source_set_priority(source, G_PRIORITY_DEFAULT);
104  g_source_set_can_recurse(source, TRUE);
105 
106  return source;
107 }
pipe_source_new
GSource * pipe_source_new(int pipefd[2], PipeSourceCallback cb, void *ctx)
This API creates a new event source "rtRemoteSource".
Definition: glib_tools.cpp:81
EventSource
Definition: glib_tools.cpp:25
TRUE
#define TRUE
Defines for TRUE/FALSE/ENABLE flags.
Definition: wifi_common_hal.h:199