summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2014-08-14 15:49:05 +0000
committerMike Buland <eichlan@xagasoft.com>2014-08-14 15:49:05 +0000
commitc5f69c22ca51510da1674bf56982f8f1e3ca4a40 (patch)
tree344332bc84359d6da4e626ede92bf31ae5d1a52b
parentd55d73c7050e6452f18678e60b42a088175cb7ce (diff)
downloadlibbu++-c5f69c22ca51510da1674bf56982f8f1e3ca4a40.tar.gz
libbu++-c5f69c22ca51510da1674bf56982f8f1e3ca4a40.tar.bz2
libbu++-c5f69c22ca51510da1674bf56982f8f1e3ca4a40.tar.xz
libbu++-c5f69c22ca51510da1674bf56982f8f1e3ca4a40.zip
Neither the Bu::Client class or the Bu::ProtocolTelnet class were threadsafe
and both really need to be. Bu::Client is used in multi-threaded applications and has been for a while, so it's a no brainer. It may need a little bit more safety added around variable access, but all the buffers are safe now. ProtocolTelnet has it's own issus, and I should probably rework a few parts of it before too long so we can better accomidate things like line editing.
-rw-r--r--src/stable/client.cpp21
-rw-r--r--src/stable/client.h3
-rw-r--r--src/stable/protocoltelnet.cpp18
-rw-r--r--src/stable/protocoltelnet.h3
4 files changed, 45 insertions, 0 deletions
diff --git a/src/stable/client.cpp b/src/stable/client.cpp
index a9deb00..ca86f37 100644
--- a/src/stable/client.cpp
+++ b/src/stable/client.cpp
@@ -12,6 +12,7 @@
12#include "bu/protocol.h" 12#include "bu/protocol.h"
13#include "bu/clientlink.h" 13#include "bu/clientlink.h"
14#include "bu/clientlinkfactory.h" 14#include "bu/clientlinkfactory.h"
15#include "bu/mutexlocker.h"
15 16
16/** Read buffer size. */ 17/** Read buffer size. */
17#define RBS (2000) // 1500 is the nominal MTU for ethernet, it's a good guess 18#define RBS (2000) // 1500 is the nominal MTU for ethernet, it's a good guess
@@ -39,6 +40,7 @@ Bu::Client::~Client()
39 40
40void Bu::Client::processInput() 41void Bu::Client::processInput()
41{ 42{
43 mRead.lock();
42 char buf[RBS]; 44 char buf[RBS];
43 Bu::size nRead, nTotal=0; 45 Bu::size nRead, nTotal=0;
44 46
@@ -67,6 +69,7 @@ void Bu::Client::processInput()
67 break; 69 break;
68 } 70 }
69 } 71 }
72 mRead.unlock();
70 73
71 if( nTotal == 0 ) 74 if( nTotal == 0 )
72 { 75 {
@@ -82,6 +85,7 @@ void Bu::Client::processInput()
82 85
83void Bu::Client::processOutput() 86void Bu::Client::processOutput()
84{ 87{
88 mWrite.lock();
85 char buf[RBS]; 89 char buf[RBS];
86 if( qbWrite.getSize() > 0 ) 90 if( qbWrite.getSize() > 0 )
87 { 91 {
@@ -91,6 +95,7 @@ void Bu::Client::processOutput()
91 qbWrite.seek( nReal ); 95 qbWrite.seek( nReal );
92 pTopStream->flush(); 96 pTopStream->flush();
93 } 97 }
98 mWrite.unlock();
94} 99}
95 100
96void Bu::Client::setProtocol( Protocol *pProto ) 101void Bu::Client::setProtocol( Protocol *pProto )
@@ -128,71 +133,85 @@ bool Bu::Client::isOpen()
128 133
129Bu::size Bu::Client::write( const Bu::String &sData ) 134Bu::size Bu::Client::write( const Bu::String &sData )
130{ 135{
136 Bu::MutexLocker l( mWrite );
131 return qbWrite.write( sData.getStr(), sData.getSize() ); 137 return qbWrite.write( sData.getStr(), sData.getSize() );
132} 138}
133 139
134Bu::size Bu::Client::write( const void *pData, Bu::size nBytes ) 140Bu::size Bu::Client::write( const void *pData, Bu::size nBytes )
135{ 141{
142 Bu::MutexLocker l( mWrite );
136 return qbWrite.write( pData, nBytes ); 143 return qbWrite.write( pData, nBytes );
137} 144}
138 145
139Bu::size Bu::Client::write( int8_t nData ) 146Bu::size Bu::Client::write( int8_t nData )
140{ 147{
148 Bu::MutexLocker l( mWrite );
141 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 149 return qbWrite.write( (const char *)&nData, sizeof(nData) );
142} 150}
143 151
144Bu::size Bu::Client::write( int16_t nData ) 152Bu::size Bu::Client::write( int16_t nData )
145{ 153{
154 Bu::MutexLocker l( mWrite );
146 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 155 return qbWrite.write( (const char *)&nData, sizeof(nData) );
147} 156}
148 157
149Bu::size Bu::Client::write( int32_t nData ) 158Bu::size Bu::Client::write( int32_t nData )
150{ 159{
160 Bu::MutexLocker l( mWrite );
151 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 161 return qbWrite.write( (const char *)&nData, sizeof(nData) );
152} 162}
153 163
154Bu::size Bu::Client::write( int64_t nData ) 164Bu::size Bu::Client::write( int64_t nData )
155{ 165{
166 Bu::MutexLocker l( mWrite );
156 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 167 return qbWrite.write( (const char *)&nData, sizeof(nData) );
157} 168}
158 169
159Bu::size Bu::Client::write( uint8_t nData ) 170Bu::size Bu::Client::write( uint8_t nData )
160{ 171{
172 Bu::MutexLocker l( mWrite );
161 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 173 return qbWrite.write( (const char *)&nData, sizeof(nData) );
162} 174}
163 175
164Bu::size Bu::Client::write( uint16_t nData ) 176Bu::size Bu::Client::write( uint16_t nData )
165{ 177{
178 Bu::MutexLocker l( mWrite );
166 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 179 return qbWrite.write( (const char *)&nData, sizeof(nData) );
167} 180}
168 181
169Bu::size Bu::Client::write( uint32_t nData ) 182Bu::size Bu::Client::write( uint32_t nData )
170{ 183{
184 Bu::MutexLocker l( mWrite );
171 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 185 return qbWrite.write( (const char *)&nData, sizeof(nData) );
172} 186}
173 187
174Bu::size Bu::Client::write( uint64_t nData ) 188Bu::size Bu::Client::write( uint64_t nData )
175{ 189{
190 Bu::MutexLocker l( mWrite );
176 return qbWrite.write( (const char *)&nData, sizeof(nData) ); 191 return qbWrite.write( (const char *)&nData, sizeof(nData) );
177} 192}
178 193
179Bu::size Bu::Client::read( void *pData, Bu::size nBytes ) 194Bu::size Bu::Client::read( void *pData, Bu::size nBytes )
180{ 195{
196 Bu::MutexLocker l( mWrite );
181 return qbRead.read( pData, nBytes ); 197 return qbRead.read( pData, nBytes );
182} 198}
183 199
184Bu::size Bu::Client::peek( void *pData, int nBytes, int nOffset ) 200Bu::size Bu::Client::peek( void *pData, int nBytes, int nOffset )
185{ 201{
202 Bu::MutexLocker l( mWrite );
186 return qbRead.peek( pData, nBytes, nOffset ); 203 return qbRead.peek( pData, nBytes, nOffset );
187} 204}
188 205
189Bu::size Bu::Client::getInputSize() 206Bu::size Bu::Client::getInputSize()
190{ 207{
208 Bu::MutexLocker l( mWrite );
191 return qbRead.getSize(); 209 return qbRead.getSize();
192} 210}
193 211
194Bu::size Bu::Client::getOutputSize() 212Bu::size Bu::Client::getOutputSize()
195{ 213{
214 Bu::MutexLocker l( mWrite );
196 return qbWrite.getSize(); 215 return qbWrite.getSize();
197} 216}
198 217
@@ -240,6 +259,7 @@ Bu::size Bu::Client::tell()
240 259
241void Bu::Client::seek( Bu::size offset ) 260void Bu::Client::seek( Bu::size offset )
242{ 261{
262 Bu::MutexLocker l( mRead );
243 return qbRead.seek( offset ); 263 return qbRead.seek( offset );
244} 264}
245 265
@@ -265,6 +285,7 @@ void Bu::Client::flush()
265 285
266bool Bu::Client::canRead() 286bool Bu::Client::canRead()
267{ 287{
288 Bu::MutexLocker l( mRead );
268 return qbRead.getSize() > 0; 289 return qbRead.getSize() > 0;
269} 290}
270 291
diff --git a/src/stable/client.h b/src/stable/client.h
index 89e8144..ac882eb 100644
--- a/src/stable/client.h
+++ b/src/stable/client.h
@@ -13,6 +13,7 @@
13#include "bu/config.h" 13#include "bu/config.h"
14#include "bu/string.h" 14#include "bu/string.h"
15#include "bu/queuebuf.h" 15#include "bu/queuebuf.h"
16#include "bu/mutex.h"
16 17
17namespace Bu 18namespace Bu
18{ 19{
@@ -127,6 +128,8 @@ namespace Bu
127 Bu::QueueBuf qbWrite; 128 Bu::QueueBuf qbWrite;
128 bool bWantsDisconnect; 129 bool bWantsDisconnect;
129 class Bu::ClientLinkFactory *pfLink; 130 class Bu::ClientLinkFactory *pfLink;
131 Bu::Mutex mRead;
132 Bu::Mutex mWrite;
130 }; 133 };
131} 134}
132 135
diff --git a/src/stable/protocoltelnet.cpp b/src/stable/protocoltelnet.cpp
index 1461b0e..153af57 100644
--- a/src/stable/protocoltelnet.cpp
+++ b/src/stable/protocoltelnet.cpp
@@ -7,6 +7,7 @@
7 7
8#include "bu/protocoltelnet.h" 8#include "bu/protocoltelnet.h"
9#include "bu/client.h" 9#include "bu/client.h"
10#include "bu/mutexlocker.h"
10 11
11/* We apparently at least want defs for the lower 13, not sure we care about 12/* We apparently at least want defs for the lower 13, not sure we care about
12 * the rest of the chars, maybe escape. 13 * the rest of the chars, maybe escape.
@@ -81,11 +82,16 @@ Bu::ProtocolTelnet::~ProtocolTelnet()
81 82
82void Bu::ProtocolTelnet::onNewConnection( Bu::Client *pClient ) 83void Bu::ProtocolTelnet::onNewConnection( Bu::Client *pClient )
83{ 84{
85 mRead.lock();
86 mWrite.lock();
84 this->pClient = pClient; 87 this->pClient = pClient;
88 mWrite.unlock();
89 mRead.unlock();
85} 90}
86 91
87void Bu::ProtocolTelnet::onNewData( Bu::Client *pClient ) 92void Bu::ProtocolTelnet::onNewData( Bu::Client *pClient )
88{ 93{
94 MutexLocker l( mRead );
89 char bc; 95 char bc;
90 int iLeft; 96 int iLeft;
91 while( (iLeft = pClient->getInputSize()) ) 97 while( (iLeft = pClient->getInputSize()) )
@@ -233,7 +239,9 @@ void Bu::ProtocolTelnet::onNewData( Bu::Client *pClient )
233 sDataBuf += bc; 239 sDataBuf += bc;
234 if( oEcho.isLocalSet() && bEcho ) 240 if( oEcho.isLocalSet() && bEcho )
235 { 241 {
242 mWrite.lock();
236 pClient->write( &bc, 1 ); 243 pClient->write( &bc, 1 );
244 mWrite.unlock();
237#ifdef __TELNET_DEBUG 245#ifdef __TELNET_DEBUG
238 printf("%c", bc ); 246 printf("%c", bc );
239 fflush( stdout ); 247 fflush( stdout );
@@ -246,7 +254,9 @@ void Bu::ProtocolTelnet::onNewData( Bu::Client *pClient )
246 sDataBuf += bc; 254 sDataBuf += bc;
247 if( oEcho.isLocalSet() && bEcho ) 255 if( oEcho.isLocalSet() && bEcho )
248 { 256 {
257 mWrite.lock();
249 pClient->write( &bc, 1 ); 258 pClient->write( &bc, 1 );
259 mWrite.unlock();
250 } 260 }
251 } 261 }
252 } 262 }
@@ -291,6 +301,7 @@ void Bu::ProtocolTelnet::write( const Bu::String &sData )
291 301
292void Bu::ProtocolTelnet::write( const char *pData, int iSize ) 302void Bu::ProtocolTelnet::write( const char *pData, int iSize )
293{ 303{
304 Bu::MutexLocker l( mWrite );
294 int iLast = 0, j; 305 int iLast = 0, j;
295 for( j = iLast; j < iSize; j++ ) 306 for( j = iLast; j < iSize; j++ )
296 { 307 {
@@ -323,11 +334,13 @@ void Bu::ProtocolTelnet::write( char cData )
323 334
324void Bu::ProtocolTelnet::flush() 335void Bu::ProtocolTelnet::flush()
325{ 336{
337 Bu::MutexLocker l( mWrite );
326 pClient->flush(); 338 pClient->flush();
327} 339}
328 340
329void Bu::ProtocolTelnet::onWill( char cCode ) 341void Bu::ProtocolTelnet::onWill( char cCode )
330{ 342{
343 Bu::MutexLocker l( mWrite );
331 try 344 try
332 { 345 {
333 Option *pOpt = hOpts[cCode]; 346 Option *pOpt = hOpts[cCode];
@@ -353,6 +366,7 @@ void Bu::ProtocolTelnet::onWill( char cCode )
353 366
354void Bu::ProtocolTelnet::onWont( char cCode ) 367void Bu::ProtocolTelnet::onWont( char cCode )
355{ 368{
369 Bu::MutexLocker l( mWrite );
356 try 370 try
357 { 371 {
358 Option *pOpt = hOpts[cCode]; 372 Option *pOpt = hOpts[cCode];
@@ -370,6 +384,7 @@ void Bu::ProtocolTelnet::onWont( char cCode )
370 384
371void Bu::ProtocolTelnet::onDo( char cCode ) 385void Bu::ProtocolTelnet::onDo( char cCode )
372{ 386{
387 Bu::MutexLocker l( mWrite );
373 try 388 try
374 { 389 {
375 Option *pOpt = hOpts[cCode]; 390 Option *pOpt = hOpts[cCode];
@@ -395,6 +410,7 @@ void Bu::ProtocolTelnet::onDo( char cCode )
395 410
396void Bu::ProtocolTelnet::onDont( char cCode ) 411void Bu::ProtocolTelnet::onDont( char cCode )
397{ 412{
413 Bu::MutexLocker l( mWrite );
398 try 414 try
399 { 415 {
400 Option *pOpt = hOpts[cCode]; 416 Option *pOpt = hOpts[cCode];
@@ -467,7 +483,9 @@ void Bu::ProtocolTelnet::onCtlChar( char cChr )
467 { 483 {
468 sDataBuf.resize( sDataBuf.getSize()-1 ); 484 sDataBuf.resize( sDataBuf.getSize()-1 );
469 char buf[3] = { CH_BS, ' ', CH_BS }; 485 char buf[3] = { CH_BS, ' ', CH_BS };
486 mWrite.lock();
470 pClient->write( buf, 3 ); 487 pClient->write( buf, 3 );
488 mWrite.unlock();
471 } 489 }
472 } 490 }
473 break; 491 break;
diff --git a/src/stable/protocoltelnet.h b/src/stable/protocoltelnet.h
index 60faef4..19298dc 100644
--- a/src/stable/protocoltelnet.h
+++ b/src/stable/protocoltelnet.h
@@ -11,6 +11,7 @@
11#include "bu/protocol.h" 11#include "bu/protocol.h"
12#include "bu/hash.h" 12#include "bu/hash.h"
13#include "bu/string.h" 13#include "bu/string.h"
14#include "bu/mutex.h"
14 15
15// #define __TELNET_DEBUG 16// #define __TELNET_DEBUG
16 17
@@ -210,6 +211,8 @@ namespace Bu
210#endif 211#endif
211 212
212 private: 213 private:
214 Mutex mRead;
215 Mutex mWrite;
213 Client *pClient; 216 Client *pClient;
214 217
215 Bu::String sDataBuf; /**< Buffer for regular line data. */ 218 Bu::String sDataBuf; /**< Buffer for regular line data. */