UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
ipc_frame_unix.cpp File Reference
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <array>
#include <string>
#include <memory>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <cerrno>
#include "ipc_frame_unix.h"
Include dependency graph for ipc_frame_unix.cpp:

Go to the source code of this file.

Classes

struct  Ipc_frame_reader
 
struct  Ipc_frame_writer
 

Macros

#define CLOSESOCKET   close
 
#define INVALID_SOCKET   -1
 
#define MSG_NOSIGNAL   0
 
#define UNLINK   unlink
 

Functions

static size_t blocking_read (fd_t fd, char *dst, size_t size)
 
static bool do_frame_read (Ipc_frame_reader *reader, Ipc_frame *dst)
 
void ipc_frame_reader_free (struct Ipc_frame_reader *reader)
 
bool ipc_frame_reader_has_frame (struct Ipc_frame_reader *reader)
 
bool ipc_frame_reader_is_connected (struct Ipc_frame_reader *reader)
 
Ipc_frame_reader * ipc_frame_reader_new (const char *path)
 
bool ipc_frame_reader_read (Ipc_frame_reader *reader, Ipc_frame *dst)
 
void ipc_frame_reader_wait_connect (struct Ipc_frame_reader *reader)
 
void ipc_frame_writer_free (struct Ipc_frame_writer *writer)
 
Ipc_frame_writer * ipc_frame_writer_new (const char *path)
 
bool ipc_frame_writer_write (struct Ipc_frame_writer *writer, const struct Ipc_frame *f)
 
static bool socket_read_avail (fd_t fd)
 
static bool try_accept (struct Ipc_frame_reader *reader)
 

Macro Definition Documentation

◆ CLOSESOCKET

#define CLOSESOCKET   close

◆ INVALID_SOCKET

◆ MSG_NOSIGNAL

#define MSG_NOSIGNAL   0

Definition at line 31 of file ipc_frame_unix.cpp.

◆ UNLINK

#define UNLINK   unlink

Definition at line 17 of file ipc_frame_unix.cpp.

Referenced by ipc_frame_reader_free(), and ipc_frame_reader_new().

Function Documentation

◆ blocking_read()

static size_t blocking_read ( fd_t fd,
char * dst,
size_t size )
static

Definition at line 103 of file ipc_frame_unix.cpp.

103 {
104 size_t bytes_read = 0;
105
106 while(bytes_read < size){
107 int read_now = recv(fd, dst + bytes_read, size - bytes_read, 0);
108 if(read_now <= 0)
109 break;
110
111 bytes_read += read_now;
112 }
113
114 return bytes_read;
115}

Referenced by do_frame_read().

◆ do_frame_read()

static bool do_frame_read ( Ipc_frame_reader * reader,
Ipc_frame * dst )
static

Definition at line 160 of file ipc_frame_unix.cpp.

160 {
161 char header_buf[IPC_FRAME_HEADER_LEN];
162
164 return false;
165
166 if(!ipc_frame_parse_header(&dst->header, header_buf))
167 return false;
168
169 if(!ipc_frame_reserve(dst, dst->header.data_len))
170 return false;
171
172 int read_data = blocking_read(reader->data_fd, dst->data, dst->header.data_len);
173
174 return read_data == dst->header.data_len;
175}
bool ipc_frame_parse_header(Ipc_frame_header *hdr, const char *buf)
Definition ipc_frame.cpp:31
bool ipc_frame_reserve(Ipc_frame *frame, size_t size)
Definition ipc_frame.cpp:66
#define IPC_FRAME_HEADER_LEN
Definition ipc_frame.h:7
static size_t blocking_read(fd_t fd, char *dst, size_t size)
Ipc_frame_header header
Definition ipc_frame.h:24
char * data
Definition ipc_frame.h:25

References blocking_read(), Ipc_frame::data, Ipc_frame_reader::data_fd, Ipc_frame_header::data_len, Ipc_frame::header, IPC_FRAME_HEADER_LEN, ipc_frame_parse_header(), and ipc_frame_reserve().

Referenced by ipc_frame_reader_read().

Here is the call graph for this function:

◆ ipc_frame_reader_free()

void ipc_frame_reader_free ( struct Ipc_frame_reader * reader)

Definition at line 92 of file ipc_frame_unix.cpp.

92 {
93 if(reader->data_fd != INVALID_SOCKET)
94 CLOSESOCKET(reader->data_fd);
95 if(reader->listen_fd != INVALID_SOCKET)
96 CLOSESOCKET(reader->listen_fd);
97
98 UNLINK(reader->path.c_str());
99
100 delete reader;
101}
#define INVALID_SOCKET
#define CLOSESOCKET
#define UNLINK

References CLOSESOCKET, Ipc_frame_reader::data_fd, INVALID_SOCKET, Ipc_frame_reader::listen_fd, Ipc_frame_reader::path, and UNLINK.

Referenced by Ipc_frame_reader_deleter::operator()().

◆ ipc_frame_reader_has_frame()

bool ipc_frame_reader_has_frame ( struct Ipc_frame_reader * reader)

Definition at line 142 of file ipc_frame_unix.cpp.

142 {
144 return false;
145
146 return socket_read_avail(reader->data_fd);
147}
bool ipc_frame_reader_is_connected(struct Ipc_frame_reader *reader)
static bool socket_read_avail(fd_t fd)

References Ipc_frame_reader::data_fd, ipc_frame_reader_is_connected(), and socket_read_avail().

Referenced by PreviewWidget::loadFrame().

Here is the call graph for this function:

◆ ipc_frame_reader_is_connected()

bool ipc_frame_reader_is_connected ( struct Ipc_frame_reader * reader)

Definition at line 149 of file ipc_frame_unix.cpp.

149 {
150 return reader->data_fd != INVALID_SOCKET || try_accept(reader);
151}
static bool try_accept(struct Ipc_frame_reader *reader)

References Ipc_frame_reader::data_fd, INVALID_SOCKET, and try_accept().

Referenced by ipc_frame_reader_has_frame(), and PreviewWidget::loadFrame().

Here is the call graph for this function:

◆ ipc_frame_reader_new()

Ipc_frame_reader * ipc_frame_reader_new ( const char * path)

Definition at line 59 of file ipc_frame_unix.cpp.

59 {
60 auto reader = std::make_unique<Ipc_frame_reader>();
61 reader->path = path;
62 reader->data_fd = INVALID_SOCKET;
63
64 reader->listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
65 if(reader->listen_fd == INVALID_SOCKET){
66 return nullptr;
67 }
68
69 sockaddr_un addr;
70 memset(&addr, 0, sizeof(addr));
71 addr.sun_family = AF_UNIX;
72 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
73 addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
74 UNLINK(path);
75
76 int ret = 0;
77 ret = bind(reader->listen_fd, (const sockaddr *) &addr, sizeof(addr.sun_path));
78 if(ret == -1){
79 CLOSESOCKET(reader->listen_fd);
80 return nullptr;
81 }
82
83 ret = listen(reader->listen_fd, 5);
84 if(ret == -1){
85 CLOSESOCKET(reader->listen_fd);
86 return nullptr;
87 }
88
89 return reader.release();
90}

References CLOSESOCKET, INVALID_SOCKET, and UNLINK.

Referenced by main(), and PreviewWidget::setKey().

◆ ipc_frame_reader_read()

bool ipc_frame_reader_read ( Ipc_frame_reader * reader,
Ipc_frame * dst )

Definition at line 177 of file ipc_frame_unix.cpp.

177 {
178 bool ret = do_frame_read(reader, dst);
179 if(!ret){
180 CLOSESOCKET(reader->data_fd);
181 reader->data_fd = INVALID_SOCKET;
182 }
183
184 return ret;
185}
static bool do_frame_read(Ipc_frame_reader *reader, Ipc_frame *dst)

References CLOSESOCKET, Ipc_frame_reader::data_fd, do_frame_read(), and INVALID_SOCKET.

Referenced by PreviewWidget::loadFrame(), and main().

Here is the call graph for this function:

◆ ipc_frame_reader_wait_connect()

void ipc_frame_reader_wait_connect ( struct Ipc_frame_reader * reader)

Definition at line 153 of file ipc_frame_unix.cpp.

153 {
154 if(reader->data_fd != INVALID_SOCKET)
155 return;
156
157 reader->data_fd = accept(reader->listen_fd, nullptr, 0);
158}

References Ipc_frame_reader::data_fd, INVALID_SOCKET, and Ipc_frame_reader::listen_fd.

Referenced by main().

◆ ipc_frame_writer_free()

void ipc_frame_writer_free ( struct Ipc_frame_writer * writer)

Definition at line 217 of file ipc_frame_unix.cpp.

217 {
218 if(writer->data_fd != INVALID_SOCKET)
219 CLOSESOCKET(writer->data_fd);
220
221 delete writer;
222}
static void * writer(void *arg)
Definition hd-rum.c:129

References CLOSESOCKET, INVALID_SOCKET, and writer().

Referenced by Ipc_frame_writer_deleter::operator()().

Here is the call graph for this function:

◆ ipc_frame_writer_new()

Ipc_frame_writer * ipc_frame_writer_new ( const char * path)

Definition at line 191 of file ipc_frame_unix.cpp.

191 {
192 auto writer = std::make_unique<Ipc_frame_writer>();
193 writer->data_fd = INVALID_SOCKET;
194
195 sockaddr_un addr;
196 memset(&addr, 0, sizeof(addr));
197 addr.sun_family = AF_UNIX;
198 strncpy(addr.sun_path, path, sizeof(addr.sun_path));
199 addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
200
201 writer->data_fd = socket(AF_UNIX, SOCK_STREAM, 0);
202 if(writer->data_fd == INVALID_SOCKET){
203 perror("ipc_frame_writer_new socket");
204 return nullptr;
205 }
206
207 int ret = connect(writer->data_fd, (const struct sockaddr *) &addr, sizeof(addr));
208 if(ret == -1){
209 perror("ipc_frame_writer_new connect");
210 CLOSESOCKET(writer->data_fd);
211 return nullptr;
212 }
213
214 return writer.release();
215}

References CLOSESOCKET, INVALID_SOCKET, and writer().

Referenced by display_unix_sock_init(), and worker().

Here is the call graph for this function:

◆ ipc_frame_writer_write()

bool ipc_frame_writer_write ( struct Ipc_frame_writer * writer,
const struct Ipc_frame * f )

Definition at line 240 of file ipc_frame_unix.cpp.

240 {
241 std::array<char, IPC_FRAME_HEADER_LEN> header;
242
243 ipc_frame_write_header(&f->header, header.data());
244
245 errno = 0;
246 block_write(writer->data_fd, header.data(), header.size());
247 block_write(writer->data_fd, f->data, f->header.data_len);
248
249 return errno == 0;
250}
void ipc_frame_write_header(const struct Ipc_frame_header *hdr, char *dst)
Definition ipc_frame.cpp:40

References Ipc_frame::data, Ipc_frame_header::data_len, Ipc_frame::header, ipc_frame_write_header(), and writer().

Referenced by display_unix_sock_run(), and worker().

Here is the call graph for this function:

◆ socket_read_avail()

static bool socket_read_avail ( fd_t fd)
static

Definition at line 117 of file ipc_frame_unix.cpp.

117 {
118 if(fd == INVALID_SOCKET)
119 return false;
120
121 fd_set fds;
122 FD_ZERO(&fds);
123 FD_SET(fd, &fds);
124
125 struct timeval tv;
126 tv.tv_sec = 0;
127 tv.tv_usec = 0;
128
129 int ret = select(fd + 1, &fds, nullptr, nullptr, &tv);
130
131 return ret > 0;
132}

References INVALID_SOCKET.

Referenced by ipc_frame_reader_has_frame(), and try_accept().

◆ try_accept()

static bool try_accept ( struct Ipc_frame_reader * reader)
static

Definition at line 134 of file ipc_frame_unix.cpp.

134 {
135 if(!socket_read_avail(reader->listen_fd))
136 return false;
137
138 reader->data_fd = accept(reader->listen_fd, nullptr, 0);
139 return true;
140}

References Ipc_frame_reader::data_fd, Ipc_frame_reader::listen_fd, and socket_read_avail().

Referenced by ipc_frame_reader_is_connected().

Here is the call graph for this function: