11
11
extern std::string szAppVersion;
12
12
13
13
#define TIMEOUT 60
14
+ #define WRITE_QUEUE_SIZE 1024
14
15
#define ADDPDUSTRING (value ) parameters.AddPart(value)
15
16
#define ADDPDUSTRINGBINARY (value ) parameters.AddPart(value, false )
16
17
#define ADDPDULONG (value ) parameters.AddLong(value)
@@ -32,8 +33,10 @@ namespace http {
32
33
b_Connected(false ),
33
34
we_locked_prefs_mutex(false ),
34
35
timeout_(TIMEOUT),
35
- timer_(io_service, boost::posix_time::seconds(TIMEOUT))
36
+ timer_(io_service, boost::posix_time::seconds(TIMEOUT)),
37
+ writeQ(WRITE_QUEUE_SIZE)
36
38
{
39
+ writePdu = NULL ;
37
40
_apikey = " " ;
38
41
_password = " " ;
39
42
_allowed_subsystems = 0 ;
@@ -47,7 +50,6 @@ namespace http {
47
50
doStop = true ;
48
51
return ;
49
52
}
50
- m_writeThread = new boost::thread (boost::bind (&CProxyClient::WriteThread, this ));
51
53
m_pWebEm = webEm;
52
54
m_pDomServ = NULL ;
53
55
Reconnect ();
@@ -132,34 +134,48 @@ namespace http {
132
134
133
135
void CProxyClient::handle_write (const boost::system::error_code& error, size_t bytes_transferred)
134
136
{
137
+ boost::mutex::scoped_lock l (writeMutex);
138
+ if (bytes_transferred < writePdu->length ()) {
139
+ _log.Log (LOG_ERROR, " PROXY: Only write %ld of %ld bytes." , bytes_transferred, writePdu->length ());
140
+ }
141
+ delete writePdu;
142
+ writePdu = NULL ;
135
143
if (error) {
136
144
_log.Log (LOG_ERROR, " PROXY: Write failed, code = %d, %s" , error.value (), error.message ().c_str ());
137
145
}
138
- writeCon.notify_one ();
146
+ ProxyPdu *pdu;
147
+ if (writeQ.pop (pdu)) {
148
+ SocketWrite (pdu);
149
+ }
139
150
}
140
151
141
- void CProxyClient::WriteThread ( )
152
+ void CProxyClient::SocketWrite (ProxyPdu *pdu )
142
153
{
143
- std::vector<boost::asio::const_buffer> _writebuf;
144
- ProxyPdu *writePdu;
145
-
146
- while ((writePdu = writeQ.Take ()) != NULL ) {
147
- boost::mutex::scoped_lock l (writeMutex);
148
- _writebuf.push_back (boost::asio::buffer (writePdu->content (), writePdu->length ()));
149
- boost::asio::async_write (_socket, _writebuf, boost::bind (&CProxyClient::handle_write, this , boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
150
- writeCon.wait (l);
151
- delete writePdu;
152
- }
153
- // end of thread
154
+ // do not call directly, use MyWrite()
155
+ writePdu = pdu;
156
+ _writebuf.clear (); // make sure
157
+ _writebuf.push_back (boost::asio::buffer (writePdu->content (), writePdu->length ()));
158
+ boost::asio::async_write (_socket, _writebuf, boost::bind (&CProxyClient::handle_write, this , boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
154
159
}
155
160
156
161
void CProxyClient::MyWrite (pdu_type type, CValueLengthPart ¶meters)
157
162
{
163
+ boost::mutex::scoped_lock l (writeMutex);
158
164
if (!b_Connected) {
159
165
return ;
160
166
}
161
- ProxyPdu *writePdu = new ProxyPdu (type, ¶meters);
162
- writeQ.Put (writePdu);
167
+ ProxyPdu *pdu= new ProxyPdu (type, ¶meters);
168
+ if (writePdu) {
169
+ // write in progress, add to queue
170
+ if (!writeQ.push (pdu)) {
171
+ _log.Log (LOG_ERROR, " PROXY: Too many writes at a time, dropping packet." );
172
+ delete pdu;
173
+ return ;
174
+ }
175
+ }
176
+ else {
177
+ SocketWrite (pdu);
178
+ }
163
179
}
164
180
165
181
void CProxyClient::LoginToService ()
@@ -623,8 +639,6 @@ namespace http {
623
639
624
640
doStop = true ;
625
641
// signal end of WriteThread
626
- writeQ.Put (NULL );
627
- m_writeThread->join ();
628
642
_socket.lowest_layer ().close ();
629
643
}
630
644
0 commit comments