1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef REMOTING_BASE_BUFFERED_SOCKET_WRITER_H_
6 #define REMOTING_BASE_BUFFERED_SOCKET_WRITER_H_
7 
8 #include <list>
9 #include <memory>
10 
11 #include "base/callback.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/synchronization/lock.h"
14 #include "base/threading/thread_checker.h"
15 #include "net/base/completion_once_callback.h"
16 #include "net/base/io_buffer.h"
17 #include "net/traffic_annotation/network_traffic_annotation.h"
18 
19 namespace net {
20 class Socket;
21 }  // namespace net
22 
23 namespace remoting {
24 
25 // BufferedSocketWriter implement write data queue for stream sockets.
26 class BufferedSocketWriter {
27  public:
28   typedef base::RepeatingCallback<int(
29       const scoped_refptr<net::IOBuffer>& buf,
30       int buf_len,
31       net::CompletionOnceCallback callback,
32       const net::NetworkTrafficAnnotationTag& traffic_annotation)>
33       WriteCallback;
34   typedef base::OnceCallback<void(int)> WriteFailedCallback;
35 
36   static std::unique_ptr<BufferedSocketWriter> CreateForSocket(
37       net::Socket* socket,
38       WriteFailedCallback write_failed_callback);
39 
40   BufferedSocketWriter();
41   virtual ~BufferedSocketWriter();
42 
43   // Starts the writer. |write_callback| is called to write data to the
44   // socket. |write_failed_callback| is called when write operation fails.
45   // Writing stops after the first failed write.
46   void Start(const WriteCallback& write_callback,
47              WriteFailedCallback write_failed_callback);
48 
49   // Puts a new data chunk in the buffer. If called before Start() then all data
50   // is buffered until Start().
51   void Write(scoped_refptr<net::IOBufferWithSize> buffer,
52              base::OnceClosure done_task,
53              const net::NetworkTrafficAnnotationTag& traffic_annotation);
54 
55   // Returns true when there is data waiting to be written.
has_data_pending()56   bool has_data_pending() { return !queue_.empty(); }
57 
58  private:
59   struct PendingPacket;
60 
61   void DoWrite();
62   void HandleWriteResult(int result);
63   void OnWritten(int result);
64 
65   base::ThreadChecker thread_checker_;
66 
67   WriteCallback write_callback_;
68   WriteFailedCallback write_failed_callback_;
69 
70   bool closed_ = false;
71 
72   std::list<std::unique_ptr<PendingPacket>> queue_;
73 
74   bool write_pending_ = false;
75 
76   base::WeakPtrFactory<BufferedSocketWriter> weak_factory_{this};
77 };
78 
79 }  // namespace remoting
80 
81 #endif  // REMOTING_BASE_BUFFERED_SOCKET_WRITER_H_
82