Open Lighting Architecture 0.10.9
Loading...
Searching...
No Matches
Descriptor.h
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * Descriptor.h
17 * The Descriptor classes
18 * Copyright (C) 2005 Simon Newton
19 */
20
21#ifndef INCLUDE_OLA_IO_DESCRIPTOR_H_
22#define INCLUDE_OLA_IO_DESCRIPTOR_H_
23
24#include <stdint.h>
25#include <unistd.h>
26#include <ola/Callback.h>
27#include <ola/base/Macro.h>
28#include <ola/io/IOQueue.h>
29#include <string>
30
31namespace ola {
32namespace io {
33
70// The following section of code defines the various types and helper functions
71// needed for the Descriptor infrastructure.
72// On *nix, there's the "everything is a file" philosophy, so we can just use
73// ints as handles.
74// On Windows, the situation is more complicated, so we need to treat sockets,
75// files, devices, pipes, etc. in special ways.
76#ifdef _WIN32
77// Internal use only. Semantic type of the descriptor.
78enum DescriptorType {
79 GENERIC_DESCRIPTOR = 0, // Catch-all type without special handling
80 SOCKET_DESCRIPTOR, // WinSock socket
81 PIPE_DESCRIPTOR // Named Pipe handle
82};
83
84// Consider this to be an opaque type.
85struct DescriptorHandle {
86 // The actual OS handle
87 union {
88 int m_fd;
89 void* m_handle;
90 } m_handle;
91 // Type of this descriptor's handle
92 DescriptorType m_type;
93 // Handler to an event for async I/O
94 void* m_event;
95 // Pointer to read result of an async I/O call
96 uint8_t* m_async_data;
97 // Pointer to size of read result data
98 uint32_t* m_async_data_size;
99
100 DescriptorHandle();
101 ~DescriptorHandle();
102
103 bool AllocAsyncBuffer();
104 void FreeAsyncBuffer();
105
106 bool IsValid() const;
107};
108
109void* ToHandle(const DescriptorHandle &handle);
110
111static DescriptorHandle INVALID_DESCRIPTOR;
112static const uint32_t ASYNC_DATA_BUFFER_SIZE = 1024;
113bool operator!=(const DescriptorHandle &lhs, const DescriptorHandle &rhs);
114bool operator==(const DescriptorHandle &lhs, const DescriptorHandle &rhs);
115bool operator<(const DescriptorHandle &lhs, const DescriptorHandle &rhs);
116std::ostream& operator<<(std::ostream &stream, const DescriptorHandle &data);
117#else
118typedef int DescriptorHandle;
119static DescriptorHandle INVALID_DESCRIPTOR = -1;
120#endif // _WIN32
121
131int ToFD(const DescriptorHandle& handle);
132
133/*
134 * A FileDescriptor which can be read from.
135 */
136
141 public:
142 virtual ~ReadFileDescriptor() {}
143
148 virtual DescriptorHandle ReadDescriptor() const = 0;
149
154 bool ValidReadDescriptor() const {
155 return ReadDescriptor() != INVALID_DESCRIPTOR;
156 }
157
163 virtual void PerformRead() = 0;
164};
165
166
171 public:
172 virtual ~WriteFileDescriptor() {}
173
178 virtual DescriptorHandle WriteDescriptor() const = 0;
179
184 bool ValidWriteDescriptor() const {
185 return WriteDescriptor() != INVALID_DESCRIPTOR;
186 }
187
193 virtual void PerformWrite() = 0;
194};
195
196
201 public WriteFileDescriptor {
202 public :
203 BidirectionalFileDescriptor(): m_on_read(NULL), m_on_write(NULL) {}
204
206 if (m_on_read)
207 delete m_on_read;
208
209 if (m_on_write)
210 delete m_on_write;
211 }
212
219 if (m_on_read)
220 delete m_on_read;
221 m_on_read = on_read;
222 }
223
230 if (m_on_write)
231 delete m_on_write;
232 m_on_write = on_write;
233 }
234
235 void PerformRead();
236 void PerformWrite();
237
238 private:
239 ola::Callback0<void> *m_on_read;
240 ola::Callback0<void> *m_on_write;
241};
242
243
248 public :
253 explicit UnmanagedFileDescriptor(int fd);
255 DescriptorHandle ReadDescriptor() const { return m_handle; }
256 DescriptorHandle WriteDescriptor() const { return m_handle; }
257
258 protected:
259 // This is only protected because WIN32-specific subclasses need access.
260 DescriptorHandle m_handle;
261
262 private:
264 const UnmanagedFileDescriptor &operator=(const UnmanagedFileDescriptor &) = delete;
265};
266
267
272 bool operator()(const ola::io::UnmanagedFileDescriptor *d1,
273 const ola::io::UnmanagedFileDescriptor *d2) const {
274 return d1->ReadDescriptor() < d2->ReadDescriptor();
275 }
276};
277
278
284 public:
286
287 ConnectedDescriptor(): BidirectionalFileDescriptor(), m_on_close(NULL) {}
288
289 virtual ~ConnectedDescriptor() {
290 if (m_on_close)
291 delete m_on_close;
292 }
293
300 virtual ssize_t Send(const uint8_t *buffer, unsigned int size);
301
312 virtual ssize_t Send(IOQueue *data);
313
314
323 virtual int Receive(uint8_t *buffer,
324 unsigned int size,
325 unsigned int &data_read); // NOLINT(runtime/references)
326
333 virtual bool SetReadNonBlocking() {
335 }
336
337 virtual bool Close() = 0;
338
343 int DataRemaining() const;
344
348 bool IsClosed() const;
349
355 void SetOnClose(OnCloseCallback *on_close) {
356 if (m_on_close)
357 delete m_on_close;
358 m_on_close = on_close;
359 }
360
371 OnCloseCallback *on_close = m_on_close;
372 m_on_close = NULL;
373 return on_close;
374 }
375
379 static bool SetNonBlocking(DescriptorHandle fd);
380
381 protected:
382 virtual bool IsSocket() const = 0;
383
387 bool SetNoSigPipe(DescriptorHandle fd);
388
389 private:
390 OnCloseCallback *m_on_close;
391};
392
393
400 public:
403
408 bool Init();
409 DescriptorHandle ReadDescriptor() const { return m_handle_pair[0]; }
410 DescriptorHandle WriteDescriptor() const { return m_handle_pair[1]; }
411
416 bool Close();
417
422 bool CloseClient();
423
424 protected:
425 bool IsSocket() const { return false; }
426
427 private:
428 DescriptorHandle m_handle_pair[2];
429
430
431 LoopbackDescriptor(const LoopbackDescriptor &) = delete;
432 const LoopbackDescriptor &operator=(const LoopbackDescriptor &) = delete;
433};
434
435
442 public:
444 ~PipeDescriptor() { Close(); }
445
449 bool Init();
450
459 DescriptorHandle ReadDescriptor() const { return m_in_pair[0]; }
460 DescriptorHandle WriteDescriptor() const { return m_out_pair[1]; }
461
465 bool Close();
466
470 bool CloseClient();
471
472 protected:
473 bool IsSocket() const { return false; }
474
475 private:
476 DescriptorHandle m_in_pair[2];
477 DescriptorHandle m_out_pair[2];
478 PipeDescriptor *m_other_end;
479
480 PipeDescriptor(DescriptorHandle in_pair[2],
481 DescriptorHandle out_pair[2],
482 PipeDescriptor *other_end);
483
484
485 PipeDescriptor(const PipeDescriptor &) = delete;
486 const PipeDescriptor &operator=(const PipeDescriptor &) = delete;
487};
488
493 public:
494 UnixSocket():
495 m_other_end(NULL) {
496 m_handle = INVALID_DESCRIPTOR;
497 }
498 ~UnixSocket() { Close(); }
499
503 bool Init();
504
513 DescriptorHandle ReadDescriptor() const { return m_handle; }
514 DescriptorHandle WriteDescriptor() const { return m_handle; }
515
519 bool Close();
520
521
525 bool CloseClient();
526
527 protected:
528 bool IsSocket() const { return true; }
529
530 private:
531 DescriptorHandle m_handle;
532 UnixSocket *m_other_end;
533 UnixSocket(int socket, UnixSocket *other_end);
534
535 UnixSocket(const UnixSocket &) = delete;
536 const UnixSocket &operator=(const UnixSocket &) = delete;
537};
538
543 public:
548 explicit DeviceDescriptor(int fd);
549 ~DeviceDescriptor() { Close(); }
550
551 DescriptorHandle ReadDescriptor() const { return m_handle; }
552 DescriptorHandle WriteDescriptor() const { return m_handle; }
553
557 bool Close();
558
559 protected:
560 bool IsSocket() const { return false; }
561
562 private:
563 DescriptorHandle m_handle;
564
565 DeviceDescriptor(const DeviceDescriptor &) = delete;
566 const DeviceDescriptor &operator=(const DeviceDescriptor &) = delete;
567};
568
570} // namespace io
571} // namespace ola
572#endif // INCLUDE_OLA_IO_DESCRIPTOR_H_
Helper macros.
A 0 argument callback which can be called multiple times.
Definition Callback.h:129
A 0 arg, single use callback that returns void.
Definition Callback.h:157
A 0 argument callback which deletes itself after it's run.
Definition Callback.h:141
A file descriptor that supports both read & write.
Definition Descriptor.h:201
void SetOnData(ola::Callback0< void > *on_read)
Set the callback to be run when data is available for reading.
Definition Descriptor.h:218
void PerformRead()
Called when there is data available on the descriptor.
Definition Descriptor.cpp:212
void SetOnWritable(ola::Callback0< void > *on_write)
Set the callback to be run when the descriptor can be written to.
Definition Descriptor.h:229
void PerformWrite()
Called when the descriptor can be written to.
Definition Descriptor.cpp:221
A BidirectionalFileDescriptor that also generates notifications when closed.
Definition Descriptor.h:283
bool IsClosed() const
Check if the descriptor is closed.
Definition Descriptor.cpp:493
OnCloseCallback * TransferOnClose()
Take ownership of the on_close callback.
Definition Descriptor.h:370
static bool SetNonBlocking(DescriptorHandle fd)
Set a DescriptorHandle to non-blocking mode.
Definition Descriptor.cpp:246
virtual int Receive(uint8_t *buffer, unsigned int size, unsigned int &data_read)
Read data from this descriptor.
Definition Descriptor.cpp:422
bool SetNoSigPipe(DescriptorHandle fd)
Disable SIGPIPE for this descriptor.
Definition Descriptor.cpp:267
void SetOnClose(OnCloseCallback *on_close)
Set the callback to be run when the descriptor is closed.
Definition Descriptor.h:355
virtual ssize_t Send(const uint8_t *buffer, unsigned int size)
Write a buffer to the descriptor.
Definition Descriptor.cpp:318
virtual bool SetReadNonBlocking()
Enable on non-blocking reads..
Definition Descriptor.h:333
int DataRemaining() const
Find out how much data is left to read.
Definition Descriptor.cpp:289
A descriptor which represents a connection to a device.
Definition Descriptor.h:542
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:551
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:552
bool Close()
Close this DeviceDescriptor.
Definition Descriptor.cpp:721
DeviceDescriptor(int fd)
Create a new DeviceDescriptor.
Definition Descriptor.cpp:712
Definition IOQueue.h:41
A loopback descriptor.
Definition Descriptor.h:399
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:410
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:409
bool Close()
Close the loopback descriptor.
Definition Descriptor.cpp:518
bool Init()
Setup this loopback descriptor.
Definition Descriptor.cpp:505
bool CloseClient()
Close the write portion of the loopback descriptor.
Definition Descriptor.cpp:540
A descriptor that uses unix pipes.
Definition Descriptor.h:441
bool Close()
Close this PipeDescriptor.
Definition Descriptor.cpp:600
bool CloseClient()
Close the write portion of this PipeDescriptor.
Definition Descriptor.cpp:622
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:459
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:460
bool Init()
Initialize the PipeDescriptor.
Definition Descriptor.cpp:562
PipeDescriptor * OppositeEnd()
Fetch the other end of the PipeDescriptor.
Definition Descriptor.cpp:588
Represents a file descriptor that supports reading data.
Definition Descriptor.h:140
virtual void PerformRead()=0
Called when there is data available on the descriptor.
virtual DescriptorHandle ReadDescriptor() const =0
Returns the read descriptor for this socket.
bool ValidReadDescriptor() const
Check if this file descriptor is valid.
Definition Descriptor.h:154
A unix domain socket pair.
Definition Descriptor.h:492
bool Close()
Close this UnixSocket.
Definition Descriptor.cpp:678
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:514
UnixSocket * OppositeEnd()
Fetch the other end of the unix socket.
Definition Descriptor.cpp:671
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:513
bool CloseClient()
Close the write portion of this UnixSocket.
Definition Descriptor.cpp:691
bool Init()
Initialize the UnixSocket.
Definition Descriptor.cpp:649
Allows a FD created by a library to be used with the SelectServer.
Definition Descriptor.h:247
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:255
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:256
UnmanagedFileDescriptor(int fd)
Create a new UnmanagedFileDescriptor.
Definition Descriptor.cpp:232
Represents a file descriptor that supports writing data.
Definition Descriptor.h:170
virtual DescriptorHandle WriteDescriptor() const =0
Returns the write descriptor for this socket.
bool ValidWriteDescriptor() const
Check if this file descriptor is valid.
Definition Descriptor.h:184
virtual void PerformWrite()=0
Called when the descriptor can be written to.
int ToFD(const DescriptorHandle &handle)
Definition Descriptor.cpp:125
The namespace containing all OLA symbols.
Definition Credentials.cpp:44
std::ostream & operator<<(std::ostream &out, const DmxBuffer &data)
Stream operator to allow DmxBuffer to be output to stdout.
Definition DmxBuffer.cpp:402
Comparison operator for UnmanagedFileDescriptor.
Definition Descriptor.h:271