Open Lighting Architecture  0.9.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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
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
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 
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_