Open Lighting Architecture  Latest Git
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
31 namespace ola {
32 namespace 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.
78 enum 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.
85 struct 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 
109 void* ToHandle(const DescriptorHandle &handle);
110 
111 static DescriptorHandle INVALID_DESCRIPTOR;
112 static const uint32_t ASYNC_DATA_BUFFER_SIZE = 1024;
113 bool operator!=(const DescriptorHandle &lhs, const DescriptorHandle &rhs);
114 bool operator==(const DescriptorHandle &lhs, const DescriptorHandle &rhs);
115 bool operator<(const DescriptorHandle &lhs, const DescriptorHandle &rhs);
116 std::ostream& operator<<(std::ostream &stream, const DescriptorHandle &data);
117 #else
118 typedef int DescriptorHandle;
119 static DescriptorHandle INVALID_DESCRIPTOR = -1;
120 #endif // _WIN32
121 
131 int 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 
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 
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:
263  DISALLOW_COPY_AND_ASSIGN(UnmanagedFileDescriptor);
264 };
265 
266 
271  bool operator()(const ola::io::UnmanagedFileDescriptor *d1,
272  const ola::io::UnmanagedFileDescriptor *d2) const {
273  return d1->ReadDescriptor() < d2->ReadDescriptor();
274  }
275 };
276 
277 
283  public:
285 
286  ConnectedDescriptor(): BidirectionalFileDescriptor(), m_on_close(NULL) {}
287 
288  virtual ~ConnectedDescriptor() {
289  if (m_on_close)
290  delete m_on_close;
291  }
292 
299  virtual ssize_t Send(const uint8_t *buffer, unsigned int size);
300 
311  virtual ssize_t Send(IOQueue *data);
312 
313 
322  virtual int Receive(uint8_t *buffer,
323  unsigned int size,
324  unsigned int &data_read); // NOLINT(runtime/references)
325 
332  virtual bool SetReadNonBlocking() {
333  return SetNonBlocking(ReadDescriptor());
334  }
335 
336  virtual bool Close() = 0;
337 
342  int DataRemaining() const;
343 
347  bool IsClosed() const;
348 
354  void SetOnClose(OnCloseCallback *on_close) {
355  if (m_on_close)
356  delete m_on_close;
357  m_on_close = on_close;
358  }
359 
369  OnCloseCallback *TransferOnClose() {
370  OnCloseCallback *on_close = m_on_close;
371  m_on_close = NULL;
372  return on_close;
373  }
374 
378  static bool SetNonBlocking(DescriptorHandle fd);
379 
380  protected:
381  virtual bool IsSocket() const = 0;
382 
386  bool SetNoSigPipe(DescriptorHandle fd);
387 
388  private:
389  OnCloseCallback *m_on_close;
390 };
391 
392 
399  public:
401  ~LoopbackDescriptor() { Close(); }
402 
407  bool Init();
408  DescriptorHandle ReadDescriptor() const { return m_handle_pair[0]; }
409  DescriptorHandle WriteDescriptor() const { return m_handle_pair[1]; }
410 
415  bool Close();
416 
421  bool CloseClient();
422 
423  protected:
424  bool IsSocket() const { return false; }
425 
426  private:
427  DescriptorHandle m_handle_pair[2];
428 
429 
430  DISALLOW_COPY_AND_ASSIGN(LoopbackDescriptor);
431 };
432 
433 
440  public:
441  PipeDescriptor();
442  ~PipeDescriptor() { Close(); }
443 
447  bool Init();
448 
457  DescriptorHandle ReadDescriptor() const { return m_in_pair[0]; }
458  DescriptorHandle WriteDescriptor() const { return m_out_pair[1]; }
459 
463  bool Close();
464 
468  bool CloseClient();
469 
470  protected:
471  bool IsSocket() const { return false; }
472 
473  private:
474  DescriptorHandle m_in_pair[2];
475  DescriptorHandle m_out_pair[2];
476  PipeDescriptor *m_other_end;
477 
478  PipeDescriptor(DescriptorHandle in_pair[2],
479  DescriptorHandle out_pair[2],
480  PipeDescriptor *other_end);
481 
482 
483  DISALLOW_COPY_AND_ASSIGN(PipeDescriptor);
484 };
485 
490  public:
491  UnixSocket():
492  m_other_end(NULL) {
493  m_handle = INVALID_DESCRIPTOR;
494  }
495  ~UnixSocket() { Close(); }
496 
500  bool Init();
501 
510  DescriptorHandle ReadDescriptor() const { return m_handle; }
511  DescriptorHandle WriteDescriptor() const { return m_handle; }
512 
516  bool Close();
517 
518 
522  bool CloseClient();
523 
524  protected:
525  bool IsSocket() const { return true; }
526 
527  private:
528  DescriptorHandle m_handle;
529  UnixSocket *m_other_end;
530  UnixSocket(int socket, UnixSocket *other_end);
531 
532  DISALLOW_COPY_AND_ASSIGN(UnixSocket);
533 };
534 
539  public:
544  explicit DeviceDescriptor(int fd);
545  ~DeviceDescriptor() { Close(); }
546 
547  DescriptorHandle ReadDescriptor() const { return m_handle; }
548  DescriptorHandle WriteDescriptor() const { return m_handle; }
549 
553  bool Close();
554 
555  protected:
556  bool IsSocket() const { return false; }
557 
558  private:
559  DescriptorHandle m_handle;
560 
561  DISALLOW_COPY_AND_ASSIGN(DeviceDescriptor);
562 };
563 
565 } // namespace io
566 } // namespace ola
567 #endif // INCLUDE_OLA_IO_DESCRIPTOR_H_
virtual void PerformRead()=0
Called when there is data available on the descriptor.
A 0 arg, single use callback that returns void.
Definition: Callback.h:157
int ToFD(const DescriptorHandle &handle)
Definition: Descriptor.cpp:125
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 BidirectionalFileDescriptor that also generates notifications when closed.
Definition: Descriptor.h:282
virtual bool SetReadNonBlocking()
Enable on non-blocking reads..
Definition: Descriptor.h:332
bool CloseClient()
Close the write portion of this UnixSocket.
Definition: Descriptor.cpp:691
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition: Descriptor.h:510
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition: Descriptor.h:457
bool CloseClient()
Close the write portion of this PipeDescriptor.
Definition: Descriptor.cpp:622
bool SetNoSigPipe(DescriptorHandle fd)
Disable SIGPIPE for this descriptor.
Definition: Descriptor.cpp:267
bool IsClosed() const
Check if the descriptor is closed.
Definition: Descriptor.cpp:493
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition: Descriptor.h:458
std::ostream & operator<<(std::ostream &out, const DmxBuffer &data)
Stream operator to allow DmxBuffer to be output to stdout.
Definition: DmxBuffer.cpp:402
virtual void PerformWrite()=0
Called when the descriptor can be written to.
A file descriptor that supports both read & write.
Definition: Descriptor.h:200
void SetOnClose(OnCloseCallback *on_close)
Set the callback to be run when the descriptor is closed.
Definition: Descriptor.h:354
void SetOnWritable(ola::Callback0< void > *on_write)
Set the callback to be run when the descriptor can be written to.
Definition: Descriptor.h:229
bool Init()
Initialize the PipeDescriptor.
Definition: Descriptor.cpp:562
virtual DescriptorHandle ReadDescriptor() const =0
Returns the read descriptor for this socket.
A descriptor that uses unix pipes.
Definition: Descriptor.h:439
DeviceDescriptor(int fd)
Create a new DeviceDescriptor.
Definition: Descriptor.cpp:712
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition: Descriptor.h:511
static bool SetNonBlocking(DescriptorHandle fd)
Set a DescriptorHandle to non-blocking mode.
Definition: Descriptor.cpp:246
Definition: IOQueue.h:40
int DataRemaining() const
Find out how much data is left to read.
Definition: Descriptor.cpp:289
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition: Descriptor.h:547
A unix domain socket pair.
Definition: Descriptor.h:489
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition: Descriptor.h:408
bool ValidWriteDescriptor() const
Check if this file descriptor is valid.
Definition: Descriptor.h:184
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition: Descriptor.h:409
PipeDescriptor * OppositeEnd()
Fetch the other end of the PipeDescriptor.
Definition: Descriptor.cpp:588
A loopback descriptor.
Definition: Descriptor.h:398
void PerformRead()
Called when there is data available on the descriptor.
Definition: Descriptor.cpp:212
Represents a file descriptor that supports reading data.
Definition: Descriptor.h:140
UnmanagedFileDescriptor(int fd)
Create a new UnmanagedFileDescriptor.
Definition: Descriptor.cpp:232
Helper macros.
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition: Descriptor.h:256
Allows a FD created by a library to be used with the SelectServer.
Definition: Descriptor.h:247
void PerformWrite()
Called when the descriptor can be written to.
Definition: Descriptor.cpp:221
void SetOnData(ola::Callback0< void > *on_read)
Set the callback to be run when data is available for reading.
Definition: Descriptor.h:218
virtual DescriptorHandle WriteDescriptor() const =0
Returns the write descriptor for this socket.
bool Close()
Close this UnixSocket.
Definition: Descriptor.cpp:678
virtual ssize_t Send(const uint8_t *buffer, unsigned int size)
Write a buffer to the descriptor.
Definition: Descriptor.cpp:318
bool Init()
Initialize the UnixSocket.
Definition: Descriptor.cpp:649
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
DescriptorHandle WriteDescriptor() const
Returns the write descriptor for this socket.
Definition: Descriptor.h:548
Comparison operator for UnmanagedFileDescriptor.
Definition: Descriptor.h:270
OnCloseCallback * TransferOnClose()
Take ownership of the on_close callback.
Definition: Descriptor.h:369
bool Close()
Close the loopback descriptor.
Definition: Descriptor.cpp:518
UnixSocket * OppositeEnd()
Fetch the other end of the unix socket.
Definition: Descriptor.cpp:671
bool Close()
Close this DeviceDescriptor.
Definition: Descriptor.cpp:721
Represents a file descriptor that supports writing data.
Definition: Descriptor.h:170
A descriptor which represents a connection to a device.
Definition: Descriptor.h:538
bool Close()
Close this PipeDescriptor.
Definition: Descriptor.cpp:600
DescriptorHandle ReadDescriptor() const
Returns the read descriptor for this socket.
Definition: Descriptor.h:255
bool ValidReadDescriptor() const
Check if this file descriptor is valid.
Definition: Descriptor.h:154
virtual int Receive(uint8_t *buffer, unsigned int size, unsigned int &data_read)
Read data from this descriptor.
Definition: Descriptor.cpp:422