Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
transceiver.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Roc authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_netio/target_libuv/roc_netio/transceiver.h
10 //! @brief Network sender/receiver.
11 
12 #ifndef ROC_NETIO_TRANSCEIVER_H_
13 #define ROC_NETIO_TRANSCEIVER_H_
14 
15 #include <uv.h>
16 
17 #include "roc_core/buffer_pool.h"
18 #include "roc_core/cond.h"
19 #include "roc_core/iallocator.h"
20 #include "roc_core/list.h"
21 #include "roc_core/list_node.h"
22 #include "roc_core/mutex.h"
23 #include "roc_core/thread.h"
24 #include "roc_netio/basic_port.h"
28 #include "roc_packet/address.h"
29 #include "roc_packet/iwriter.h"
30 #include "roc_packet/packet_pool.h"
31 
32 namespace roc {
33 namespace netio {
34 
35 //! Network sender/receiver.
36 class Transceiver : private ICloseHandler, private core::Thread {
37 public:
38  //! Initialize.
39  //!
40  //! @remarks
41  //! Start background thread if the object was successfully constructed.
42  Transceiver(packet::PacketPool& packet_pool,
43  core::BufferPool<uint8_t>& buffer_pool,
44  core::IAllocator& allocator);
45 
46  //! Destroy. Stop all receivers and senders.
47  //!
48  //! @remarks
49  //! Wait until background thread finishes.
50  virtual ~Transceiver();
51 
52  //! Check if transceiver was successfully constructed.
53  bool valid() const;
54 
55  //! Get number of receiver and sender ports.
56  size_t num_ports() const;
57 
58  //! Add UDP datagram receiver port.
59  //!
60  //! Creates a new UDP receiver and bind it to @p bind_address. The receiver
61  //! will pass packets to @p writer. Writer will be called from the network
62  //! thread. It should not block.
63  //!
64  //! If IP is zero, INADDR_ANY is used, i.e. the socket is bound to all network
65  //! interfaces. If port is zero, a random free port is selected and written
66  //! back to @p bind_address.
67  //!
68  //! @returns
69  //! true on success or false if error occurred
70  bool add_udp_receiver(packet::Address& bind_address, packet::IWriter& writer);
71 
72  //! Add UDP datagram sender port.
73  //!
74  //! Creates a new UDP sender, bind to @p bind_address, and returns a writer
75  //! that may be used to send packets from this address. Writer may be called
76  //! from any thread. It will not block the caller.
77  //!
78  //! If IP is zero, INADDR_ANY is used, i.e. the socket is bound to all network
79  //! interfaces. If port is zero, a random free port is selected and written
80  //! back to @p bind_address.
81  //!
82  //! @returns
83  //! a new packet writer on success or null if error occurred
85 
86  //! Remove sender or receiver port. Wait until port will be removed.
87  void remove_port(packet::Address bind_address);
88 
89 private:
90  struct Task : core::ListNode {
91  bool (Transceiver::*fn)(Task&);
92 
93  packet::Address* address;
94  packet::IWriter* writer;
95  BasicPort* port;
96 
97  bool result;
98  bool done;
99 
100  Task()
101  : fn(NULL)
102  , address(NULL)
103  , writer(NULL)
104  , port(NULL)
105  , result(false)
106  , done(false) {
107  }
108  };
109 
110  static void task_sem_cb_(uv_async_t* handle);
111  static void stop_sem_cb_(uv_async_t* handle);
112 
113  virtual void handle_closed(BasicPort&);
114  virtual void run();
115 
116  void close_sems_();
117  void async_close_ports_();
118 
119  void process_tasks_();
120  void run_task_(Task&);
121 
122  bool add_udp_receiver_(Task&);
123  bool add_udp_sender_(Task&);
124 
125  bool remove_port_(Task&);
126  void wait_port_closed_(const BasicPort& port);
127  bool port_is_closing_(const BasicPort& port);
128 
129  packet::PacketPool& packet_pool_;
130  core::BufferPool<uint8_t>& buffer_pool_;
131  core::IAllocator& allocator_;
132 
133  bool started_;
134 
135  uv_loop_t loop_;
136  bool loop_initialized_;
137 
138  uv_async_t stop_sem_;
139  bool stop_sem_initialized_;
140 
141  uv_async_t task_sem_;
142  bool task_sem_initialized_;
143 
145 
146  core::List<BasicPort> open_ports_;
147  core::List<BasicPort> closing_ports_;
148 
149  core::Mutex mutex_;
150  core::Cond cond_;
151 };
152 
153 } // namespace netio
154 } // namespace roc
155 
156 #endif // ROC_NETIO_TRANSCEIVER_H_
Memory allocator interface.
Definition: iallocator.h:23
void remove_port(packet::Address bind_address)
Remove sender or receiver port. Wait until port will be removed.
bool add_udp_receiver(packet::Address &bind_address, packet::IWriter &writer)
Add UDP datagram receiver port.
Base class for thread objects.
Definition: thread.h:25
Packet pool.
Condition variable.
Definition: cond.h:25
Base class for list element.
Definition: list_node.h:26
Root namespace.
Close handler interface.
Linked list node.
Close handler.
UDP receiver.
Mutex.
Definition: mutex.h:27
Thread.
Packet writer interface.
Basic port interface.
Definition: basic_port.h:24
Network address.
Definition: address.h:24
packet::IWriter * add_udp_sender(packet::Address &bind_address)
Add UDP datagram sender port.
Packet writer interface.
Definition: iwriter.h:21
Network address.
Intrusive doubly-linked list.
size_t num_ports() const
Get number of receiver and sender ports.
Mutex.
Network sender/receiver.
Definition: transceiver.h:36
virtual ~Transceiver()
Destroy. Stop all receivers and senders.
UDP sender.
Buffer pool.
Condition variable.
Basic network port.
bool valid() const
Check if transceiver was successfully constructed.
Memory allocator interface.
Transceiver(packet::PacketPool &packet_pool, core::BufferPool< uint8_t > &buffer_pool, core::IAllocator &allocator)
Initialize.