Open Lighting Architecture: include/ola/io/Descriptor.h Source File

| 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
62
69
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
140 class ReadFileDescriptor {
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
170 class WriteFileDescriptor {
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
200 class BidirectionalFileDescriptor: public ReadFileDescriptor,
201 public WriteFileDescriptor {
202 public :
203 BidirectionalFileDescriptor(): m_on_read(NULL), m_on_write(NULL) {}
204
205 virtual ~BidirectionalFileDescriptor() {
206 if (m_on_read)
207 delete m_on_read;
208
209 if (m_on_write)
210 delete m_on_write;
211 }
212
218 void SetOnData(ola::Callback0<void> *on_read) {
219 if (m_on_read)
220 delete m_on_read;
221 m_on_read = on_read;
222 }
223
229 void SetOnWritable(ola::Callback0<void> *on_write) {
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
247 class UnmanagedFileDescriptor: public BidirectionalFileDescriptor {
248 public :
253 explicit UnmanagedFileDescriptor(int fd);
254 ~UnmanagedFileDescriptor() {}
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:
263 UnmanagedFileDescriptor(const UnmanagedFileDescriptor &) = delete;
264 const UnmanagedFileDescriptor &operator=(const UnmanagedFileDescriptor &) = delete;
265};
266
267
271 struct UnmanagedFileDescriptor_lt {
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
283 class ConnectedDescriptor: public BidirectionalFileDescriptor {
284 public:
285 typedef ola::SingleUseCallback0<void> OnCloseCallback;
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() {
334 return SetNonBlocking(ReadDescriptor());
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
370 OnCloseCallback *TransferOnClose() {
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
399 class LoopbackDescriptor: public ConnectedDescriptor {
400 public:
401 LoopbackDescriptor();
402 ~LoopbackDescriptor() { Close(); }
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
441 class PipeDescriptor: public ConnectedDescriptor {
442 public:
443 PipeDescriptor();
444 ~PipeDescriptor() { Close(); }
445
449 bool Init();
450
458 PipeDescriptor *OppositeEnd();
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
492 class UnixSocket: public ConnectedDescriptor {
493 public:
494 UnixSocket():
495 m_other_end(NULL) {
496 m_handle = INVALID_DESCRIPTOR;
497 }
498 ~UnixSocket() { Close(); }
499
503 bool Init();
504
512 UnixSocket *OppositeEnd();
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
542 class DeviceDescriptor: public ConnectedDescriptor {
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_
Callback.h
Macro.h
Helper macros.
ola::Callback0
A 0 argument callback which can be called multiple times.
Definition Callback.h:129
ola::SingleUseCallback0
A 0 argument callback which deletes itself after it's run.
Definition Callback.h:141
ola::http::UnmanagedFileDescriptor::UnmanagedFileDescriptor
UnmanagedFileDescriptor(int fd)
Create a new UnmanagedFileDescriptor.
Definition Descriptor.cpp:232
ola::io::BidirectionalFileDescriptor::SetOnData
void SetOnData(ola::Callback0< void > *on_read)
Set the callback to be run when data is available for reading.
Definition Descriptor.h:218
ola::io::BidirectionalFileDescriptor::PerformRead
void PerformRead()
Called when there is data available on the descriptor.
Definition Descriptor.cpp:212
ola::io::BidirectionalFileDescriptor::SetOnWritable
void SetOnWritable(ola::Callback0< void > *on_write)
Set the callback to be run when the descriptor can be written to.
Definition Descriptor.h:229
ola::io::BidirectionalFileDescriptor::PerformWrite
void PerformWrite()
Called when the descriptor can be written to.
Definition Descriptor.cpp:221
ola::io::ConnectedDescriptor::IsClosed
bool IsClosed() const
Check if the descriptor is closed.
Definition Descriptor.cpp:493
ola::io::ConnectedDescriptor::TransferOnClose
OnCloseCallback * TransferOnClose()
Take ownership of the on_close callback.
Definition Descriptor.h:370
ola::io::ConnectedDescriptor::SetNonBlocking
static bool SetNonBlocking(DescriptorHandle fd)
Set a DescriptorHandle to non-blocking mode.
Definition Descriptor.cpp:246
ola::io::ConnectedDescriptor::Receive
virtual int Receive(uint8_t *buffer, unsigned int size, unsigned int &data_read)
Read data from this descriptor.
Definition Descriptor.cpp:422
ola::io::ConnectedDescriptor::SetNoSigPipe
bool SetNoSigPipe(DescriptorHandle fd)
Disable SIGPIPE for this descriptor.
Definition Descriptor.cpp:267
ola::io::ConnectedDescriptor::SetOnClose
void SetOnClose(OnCloseCallback *on_close)
Set the callback to be run when the descriptor is closed.
Definition Descriptor.h:355
ola::io::ConnectedDescriptor::Send
virtual ssize_t Send(const uint8_t *buffer, unsigned int size)
Write a buffer to the descriptor.
Definition Descriptor.cpp:318
ola::io::ConnectedDescriptor::SetReadNonBlocking
virtual bool SetReadNonBlocking()
Enable on non-blocking reads..
Definition Descriptor.h:333
ola::io::ConnectedDescriptor::DataRemaining
int DataRemaining() const
Find out how much data is left to read.
Definition Descriptor.cpp:289
ola::io::DeviceDescriptor::ReadDescriptor
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:551
ola::io::DeviceDescriptor::WriteDescriptor
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:552
ola::io::DeviceDescriptor::Close
bool Close()
Close this DeviceDescriptor.
Definition Descriptor.cpp:721
ola::io::DeviceDescriptor::DeviceDescriptor
DeviceDescriptor(int fd)
Create a new DeviceDescriptor.
Definition Descriptor.cpp:712
ola::io::LoopbackDescriptor::WriteDescriptor
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:410
ola::io::LoopbackDescriptor::ReadDescriptor
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:409
ola::io::LoopbackDescriptor::Close
bool Close()
Close the loopback descriptor.
Definition Descriptor.cpp:518
ola::io::LoopbackDescriptor::Init
bool Init()
Setup this loopback descriptor.
Definition Descriptor.cpp:505
ola::io::LoopbackDescriptor::CloseClient
bool CloseClient()
Close the write portion of the loopback descriptor.
Definition Descriptor.cpp:540
ola::io::PipeDescriptor::Close
bool Close()
Close this PipeDescriptor.
Definition Descriptor.cpp:600
ola::io::PipeDescriptor::CloseClient
bool CloseClient()
Close the write portion of this PipeDescriptor.
Definition Descriptor.cpp:622
ola::io::PipeDescriptor::ReadDescriptor
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:459
ola::io::PipeDescriptor::WriteDescriptor
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:460
ola::io::PipeDescriptor::Init
bool Init()
Initialize the PipeDescriptor.
Definition Descriptor.cpp:562
ola::io::PipeDescriptor::OppositeEnd
PipeDescriptor * OppositeEnd()
Fetch the other end of the PipeDescriptor.
Definition Descriptor.cpp:588
ola::io::ReadFileDescriptor
Represents a file descriptor that supports reading data.
Definition Descriptor.h:140
ola::io::ReadFileDescriptor::PerformRead
virtual void PerformRead()=0
Called when there is data available on the descriptor.
ola::io::ReadFileDescriptor::ReadDescriptor
virtual DescriptorHandle ReadDescriptor() const =0
Returns the read descriptor for this socket.
ola::io::ReadFileDescriptor::ValidReadDescriptor
bool ValidReadDescriptor() const
Check if this file descriptor is valid.
Definition Descriptor.h:154
ola::io::UnixSocket::Close
bool Close()
Close this UnixSocket.
Definition Descriptor.cpp:678
ola::io::UnixSocket::WriteDescriptor
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:514
ola::io::UnixSocket::OppositeEnd
UnixSocket * OppositeEnd()
Fetch the other end of the unix socket.
Definition Descriptor.cpp:671
ola::io::UnixSocket::ReadDescriptor
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:513
ola::io::UnixSocket::CloseClient
bool CloseClient()
Close the write portion of this UnixSocket.
Definition Descriptor.cpp:691
ola::io::UnixSocket::Init
bool Init()
Initialize the UnixSocket.
Definition Descriptor.cpp:649
ola::io::UnmanagedFileDescriptor
Allows a FD created by a library to be used with the SelectServer.
Definition Descriptor.h:247
ola::io::UnmanagedFileDescriptor::ReadDescriptor
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition Descriptor.h:255
ola::io::UnmanagedFileDescriptor::WriteDescriptor
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition Descriptor.h:256
ola::io::UnmanagedFileDescriptor::UnmanagedFileDescriptor
UnmanagedFileDescriptor(int fd)
Create a new UnmanagedFileDescriptor.
Definition Descriptor.cpp:232
ola::io::WriteFileDescriptor
Represents a file descriptor that supports writing data.
Definition Descriptor.h:170
ola::io::WriteFileDescriptor::WriteDescriptor
virtual DescriptorHandle WriteDescriptor() const =0
Returns the write descriptor for this socket.
ola::io::WriteFileDescriptor::ValidWriteDescriptor
bool ValidWriteDescriptor() const
Check if this file descriptor is valid.
Definition Descriptor.h:184
ola::io::WriteFileDescriptor::PerformWrite
virtual void PerformWrite()=0
Called when the descriptor can be written to.
ola::io::ToFD
int ToFD(const DescriptorHandle &handle)
Definition Descriptor.cpp:125
ola::io
Classes for general I/O and event handling.
Definition Descriptor.cpp:49
ola
The namespace containing all OLA symbols.
Definition Credentials.cpp:44
ola::operator<<
std::ostream & operator<<(std::ostream &out, const DmxBuffer &data)
Stream operator to allow DmxBuffer to be output to stdout.
Definition DmxBuffer.cpp:402
ola::io::UnmanagedFileDescriptor_lt
Comparison operator for UnmanagedFileDescriptor.
Definition Descriptor.h:271