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 2018 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 #include "glib_tools.h"
20 
21 #include <unistd.h>
22 #include <errno.h>
23 #include <stdio.h>
24 
25 class EventSource {
26 public:
27  static GSourceFuncs sourceFuncs;
28  GSource src;
29  GPollFD pfd;
30  PipeSourceCallback cb;
31  void* ctx;
32 };
33 
34 gboolean g_prepare (GSource*, gint *timeout_)
35 {
36  *timeout_ = -1;
37  return FALSE;
38 }
39 gboolean g_check (GSource *base)
40 {
41  auto* source = reinterpret_cast<EventSource*>(base);
42  return !!source->pfd.revents;
43 }
44 gboolean g_dispatch (GSource *base,
45  GSourceFunc callback,
46  gpointer user_data)
47 {
48  auto* source = reinterpret_cast<EventSource*>(base);
49  if (source->pfd.revents & G_IO_IN)
50  {
51  // read one byte from file
52  // and fire callback
53  // thread will not block here.
54  static char discard[1];
55  int ret = HANDLE_EINTR_EAGAIN(read(source->pfd.fd, discard, 1));
56  if (-1 == ret)
57  perror("unable to read from pipe");
58 
59  source->cb(source->ctx);
60  }
61 
62  if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
63  {
64  // TODO: improve logging?
65  puts("ERROR during read from file descriptor");
66  return FALSE;
67  }
68 
69  source->pfd.revents = 0;
70  return TRUE;
71 }
72 
73 GSourceFuncs EventSource::sourceFuncs =
74 {
75  g_prepare,
76  g_check,
77  g_dispatch,
78  NULL
79 };
80 
81 GSource* pipe_source_new(int pipefd[2], PipeSourceCallback cb, void* ctx)
82 {
83  // create source
84  auto* Esource = (EventSource*)g_source_new(&EventSource::sourceFuncs, sizeof(EventSource));
85 
86  auto* source = (GSource*) Esource;
87 
88  // create pipe
89  int ret = pipe(pipefd);
90  if (ret == -1)
91  perror("can't create pipe");
92 
93  // attach pipe out FD to source
94  Esource->pfd.fd = pipefd[PIPE_LISTEN];
95  Esource->pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
96  Esource->pfd.revents = 0;
97  Esource->cb = cb;
98  Esource->ctx = ctx;
99  g_source_add_poll(source, &Esource->pfd);
100 
101  g_source_set_name(source, "rtRemoteSource");
102  g_source_set_priority(source, G_PRIORITY_DEFAULT);
103  g_source_set_can_recurse(source, TRUE);
104 
105  return source;
106 }
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