Index: tools/android/forwarder2/device_listener.h |
diff --git a/tools/android/forwarder2/device_listener.h b/tools/android/forwarder2/device_listener.h |
index 44d37aa4ff0b9ce7087061f0228d460414df72b0..2a6982319631ed40a0df87c34127345d6077c34c 100644 |
--- a/tools/android/forwarder2/device_listener.h |
+++ b/tools/android/forwarder2/device_listener.h |
@@ -5,76 +5,106 @@ |
#ifndef TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_ |
#define TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_ |
-#include <pthread.h> |
- |
#include "base/basictypes.h" |
+#include "base/callback.h" |
#include "base/compiler_specific.h" |
#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/threading/thread.h" |
#include "tools/android/forwarder2/pipe_notifier.h" |
#include "tools/android/forwarder2/socket.h" |
-#include "tools/android/forwarder2/thread.h" |
+ |
+namespace base { |
+class SingleThreadTaskRunner; |
+} // namespace base |
namespace forwarder2 { |
class Forwarder; |
-class DeviceListener : public Thread { |
+// A DeviceListener instance is used in the device_forwarder program to bind to |
+// a specific device-side |port| and wait for client connections. When a |
+// connection happens, it informs the corresponding HostController instance |
+// running on the host, through |host_socket|. Then the class expects a call to |
+// its SetAdbDataSocket() method (performed by the device controller) once the |
+// host opened a new connection to the device. When this happens, a new internal |
+// Forwarder instance is started. |
+// Note that instances of this class are owned by the device controller which |
+// creates and destroys them on the same thread. In case an internal error |
+// happens on the DeviceListener's internal thread, the DeviceListener |
+// can also self-delete by executing the user-provided callback on the thread |
+// the DeviceListener was created on. |
+// Note that the DeviceListener's destructor joins its internal thread (i.e. |
+// waits for its completion) which means that the internal thread is guaranteed |
+// not to be running anymore once the object is deleted. |
+class DeviceListener { |
public: |
- DeviceListener(scoped_ptr<Socket> adb_control_socket, int port); |
- virtual ~DeviceListener(); |
+ // Callback that is used for self-deletion as a way to let the device |
+ // controller perform some additional cleanup work (e.g. removing the device |
+ // listener instance from its internal map before deleting it). |
+ typedef base::Callback<void (int /* listener port */)> DeleteCallback; |
- bool WaitForAdbDataSocket(); |
+ static scoped_ptr<DeviceListener> Create( |
+ scoped_ptr<Socket> host_socket, |
+ int port, |
+ const DeleteCallback& delete_callback); |
- bool SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket); |
+ ~DeviceListener(); |
- bool BindListenerSocket(); |
+ void Start(); |
- // |is_alive_| is set only on BindAndListenSocket and written once when Run() |
- // terminates. So even in case of a race condition, the worst that could |
- // happen is for the main thread to see the listener alive when it isn't. And |
- // also, this is not a problem since the main thread checks the liveliness of |
- // the listeners in a loop. |
- bool is_alive() const { return is_alive_; } |
- void ForceExit(); |
+ void SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket); |
int listener_port() const { return listener_port_; } |
- protected: |
- // Thread: |
- virtual void Run() OVERRIDE; |
- |
private: |
- void RunInternal(); |
- |
- // Must be called after successfully acquired mutex. |
- void SetMustExitLocked(); |
- |
- // The listener socket for sending control commands. |
- scoped_ptr<Socket> adb_control_socket_; |
- |
+ DeviceListener(scoped_ptr<PipeNotifier> pipe_notifier, |
+ scoped_ptr<Socket> listener_socket, |
+ scoped_ptr<Socket> host_socket, |
+ int port, |
+ const DeleteCallback& delete_callback); |
+ |
+ // Pushes an AcceptClientOnInternalThread() task to the internal thread's |
+ // message queue in order to wait for a new client soon. |
+ void AcceptNextClientSoon(); |
+ |
+ void AcceptClientOnInternalThread(); |
+ |
+ void OnAdbDataSocketReceivedOnInternalThread( |
+ scoped_ptr<Socket> adb_data_socket); |
+ |
+ void SelfDelete(); |
+ |
+ // Note that this can be called after the DeviceListener instance gets deleted |
+ // which is why this method is static. |
+ static void SelfDeleteOnDeletionTaskRunner( |
+ const DeleteCallback& delete_callback, |
+ int listener_port); |
+ |
+ // Used for the listener thread to be notified on destruction. We have one |
+ // notifier per Listener thread since each Listener thread may be requested to |
+ // exit for different reasons independently from each other and independent |
+ // from the main program, ex. when the host requests to forward/listen the |
+ // same port again. Both the |host_socket_| and |listener_socket_| |
+ // must share the same receiver file descriptor from |exit_notifier_| and it |
+ // is set in the constructor. |
+ const scoped_ptr<PipeNotifier> exit_notifier_; |
// The local device listener socket for accepting connections from the local |
// port (listener_port_). |
- Socket listener_socket_; |
- |
+ const scoped_ptr<Socket> listener_socket_; |
+ // The listener socket for sending control commands. |
+ const scoped_ptr<Socket> host_socket_; |
+ scoped_ptr<Socket> device_data_socket_; |
// This is the adb connection to transport the actual data, used for creating |
// the forwarder. Ownership transferred to the Forwarder. |
scoped_ptr<Socket> adb_data_socket_; |
- |
- int listener_port_; |
- pthread_mutex_t adb_data_socket_mutex_; |
- pthread_cond_t adb_data_socket_cond_; |
- bool is_alive_; |
- bool must_exit_; |
- |
- // Used for the listener thread to be notified from ForceExit() which is |
- // called from the main thread. We have one notifier per Listener thread since |
- // each Listener thread may be requested to exit for different reasons |
- // independently from each other and independent from the main program, |
- // ex. when the host requests to forward/listen the same port again. Both the |
- // |adb_control_socket_| and |listener_socket_| must share the same receiver |
- // file descriptor from |exit_notifier_| and it is set in the constructor. |
- PipeNotifier exit_notifier_; |
+ const int listener_port_; |
+ const DeleteCallback delete_callback_; |
+ // Task runner used for deletion set at construction time (i.e. the object is |
+ // deleted on the same thread it is created on). |
+ scoped_refptr<base::SingleThreadTaskRunner> deletion_task_runner_; |
+ base::Thread thread_; |
DISALLOW_COPY_AND_ASSIGN(DeviceListener); |
}; |