@@ -159,7 +159,7 @@ namespace lacewing
159
159
std::shared_ptr<relayclient::channel> relayclientinternal::findchannelbyid (unsigned short id)
160
160
{
161
161
lacewing::readlock rl = this ->client .lock .createReadLock ();
162
- auto i = std::find_if (channels.cbegin (), channels.cend (),
162
+ auto i = std::find_if (channels.cbegin (), channels.cend (),
163
163
[&](const std::shared_ptr<const relayclient::channel> &c) { return c->id () == id; });
164
164
return i == channels.cend () ? nullptr : *i;
165
165
}
@@ -170,7 +170,7 @@ namespace lacewing
170
170
171
171
/* opening 0 byte */
172
172
socket->write (" " , 1 );
173
-
173
+
174
174
// internal.udp->host(socket->server_address(), nullptr, 0U);
175
175
176
176
framebuilder &message = internal.message ;
@@ -211,7 +211,7 @@ namespace lacewing
211
211
char * dataCpy = (char *)malloc (size);
212
212
if (!dataCpy)
213
213
throw std::exception (" Out of memory." );
214
-
214
+
215
215
memcpy (dataCpy, data, size);
216
216
217
217
internal.reader .process (dataCpy, size);
@@ -364,7 +364,7 @@ namespace lacewing
364
364
void relayclient::join (std::string_view channelName, bool hidden, bool autoclose)
365
365
{
366
366
relayclientinternal &internal = *((relayclientinternal *)internaltag);
367
-
367
+
368
368
if (name ().empty ())
369
369
{
370
370
error error = lacewing::error_new ();
@@ -541,7 +541,7 @@ namespace lacewing
541
541
lacewing::readlock rl = lock.createReadLock ();
542
542
return _id;
543
543
}
544
-
544
+
545
545
std::string relayclient::channel::peer::name () const
546
546
{
547
547
lacewing::readlock rl = lock.createReadLock ();
@@ -559,14 +559,14 @@ namespace lacewing
559
559
// Atomic, no point changing it
560
560
return _readonly;
561
561
}
562
-
562
+
563
563
size_t relayclient::channelcount () const
564
564
{
565
565
lacewing::readlock rl = lock.createReadLock ();
566
566
return ((relayclientinternal *)internaltag)->channels .size ();
567
567
}
568
568
569
- int relayclient::id () const
569
+ lw_ui16 relayclient::id () const
570
570
{
571
571
lacewing::readlock rl = lock.createReadLock ();
572
572
return ((relayclientinternal *)internaltag)->id ;
@@ -587,8 +587,8 @@ namespace lacewing
587
587
588
588
bool relayclientinternal::messagehandler (unsigned char type, const char * message, size_t size, bool blasted)
589
589
{
590
- unsigned char messagetypeid = (type >> 4 );
591
- unsigned char variant = (type << 4 );
590
+ lw_ui8 messagetypeid = (type >> 4 );
591
+ lw_ui8 variant = (type << 4 );
592
592
593
593
variant >>= 4 ;
594
594
@@ -598,8 +598,8 @@ namespace lacewing
598
598
{
599
599
case 0 : /* response */
600
600
{
601
- unsigned char responsetype = reader.get <unsigned char >();
602
- bool succeeded = reader.get <unsigned char >() != 0 ;
601
+ lw_ui8 responsetype = reader.get <lw_ui8 >();
602
+ bool succeeded = reader.get <lw_ui8 >() != 0 ;
603
603
604
604
if (reader.failed )
605
605
break ;
@@ -610,14 +610,14 @@ namespace lacewing
610
610
{
611
611
if (succeeded)
612
612
{
613
- id = reader.get <unsigned short >();
613
+ id = reader.get <lw_ui16 >();
614
614
615
615
// Don't expect welcome message to be null terminated
616
616
std::string_view welcomemessage = reader.get (reader.bytesleft ());
617
617
618
618
if (reader.failed )
619
619
break ;
620
-
620
+
621
621
this ->welcomemessage = welcomemessage;
622
622
623
623
socket->server_address ()->resolve ();
@@ -712,16 +712,16 @@ namespace lacewing
712
712
713
713
auto channel = std::make_shared<relayclient::channel>(*this );
714
714
auto channelWriteLock = channel->lock .createWriteLock ();
715
-
715
+
716
716
channel->_id = channelid;
717
717
channel->_name = name;
718
718
channel->_ischannelmaster = (flags & 1 ) != 0 ;
719
719
720
720
for (; reader.bytesleft () > 0 ;)
721
721
{
722
- int peerid = reader.get <unsigned short >();
723
- int flags2 = reader.get <unsigned char >();
724
- int namelength2 = reader.get <unsigned char >();
722
+ lw_ui16 peerid = reader.get <lw_ui16 >();
723
+ lw_ui8 flags2 = reader.get <lw_ui8 >();
724
+ lw_ui8 namelength2 = reader.get <lw_ui8 >();
725
725
std::string_view name2 = reader.get (namelength2);
726
726
727
727
if (reader.failed )
@@ -781,7 +781,7 @@ namespace lacewing
781
781
782
782
if (handler_channel_leave)
783
783
handler_channel_leave (client, channel);
784
-
784
+
785
785
// Handler BEFORE finding it in channel list, in case leave handler calls disconnect.
786
786
if (!connected)
787
787
break ;
@@ -953,8 +953,8 @@ namespace lacewing
953
953
954
954
case 4 : /* binaryserverchannelmessage */
955
955
{
956
- int subchannel = reader.get <unsigned char >();
957
- unsigned short channel = reader.get <unsigned short >();
956
+ lw_ui8 subchannel = reader.get <lw_ui8 >();
957
+ lw_ui16 channel = reader.get <lw_ui16 >();
958
958
if (reader.failed )
959
959
break ;
960
960
@@ -1033,7 +1033,7 @@ namespace lacewing
1033
1033
1034
1034
lw_ui8 flags = reader.get <lw_ui8>();
1035
1035
std::string_view name = reader.get (reader.bytesleft ()); // name's not null terminated
1036
-
1036
+
1037
1037
if (reader.failed )
1038
1038
{
1039
1039
/* no flags/name - the peer must have left the channel */
@@ -1044,9 +1044,12 @@ namespace lacewing
1044
1044
return true ;
1045
1045
1046
1046
peer->_readonly = true ;
1047
+
1048
+ channelWriteLock.lw_unlock (); // Don't leave it locked while handler is run
1049
+
1047
1050
if (handler_peer_disconnect)
1048
1051
handler_peer_disconnect (client, channel2, peer);
1049
-
1052
+
1050
1053
channel2 = findchannelbyid (channel);
1051
1054
1052
1055
// Handler called disconnect, so channel is no longer accessible
@@ -1055,6 +1058,7 @@ namespace lacewing
1055
1058
1056
1059
// LW_ESCALATION_NOTE
1057
1060
// auto channelWriteLock = channelReadLock.lw_upgrade();
1061
+ channelWriteLock.lw_relock ();
1058
1062
auto i = std::find_if (channel2->peers .begin (), channel2->peers .end (),
1059
1063
[=](std::shared_ptr<relayclient::channel::peer> &p) { return p->_id == peerid; });
1060
1064
if (i != channel2->peers .end ())
@@ -1074,6 +1078,8 @@ namespace lacewing
1074
1078
1075
1079
// this does channel2->peers.push_back()
1076
1080
peer = channel2->addnewpeer (peerid, flags, name);
1081
+
1082
+ channelWriteLock.lw_unlock (); // Don't leave it locked while handler is run (when escalation happens, it will unlock by {}s
1077
1083
}
1078
1084
1079
1085
if (handler_peer_connect)
@@ -1244,8 +1250,8 @@ namespace lacewing
1244
1250
// udphellotick just sends UDPHello every 0.5s, and is managed by the relayclientinternal::udphellotimer var.
1245
1251
// It starts from the time the Connect Request Success message is sent.
1246
1252
if (!udp->hosting ())
1247
- throw std::exception (" udphellotick() called, but not hosting UDP." );
1248
-
1253
+ throw std::exception (" udphellotick() called, but not hosting UDP." );
1254
+
1249
1255
message.addheader (7 , 0 , true , id); /* udphello */
1250
1256
message.send (udp, socket->server_address ());
1251
1257
}
@@ -1336,7 +1342,7 @@ namespace lacewing
1336
1342
return _ischannelmaster;
1337
1343
}
1338
1344
1339
- unsigned short relayclient::channel::peer::id () const
1345
+ lw_ui16 relayclient::channel::peer::id () const
1340
1346
{
1341
1347
// We won't check for read lock, as ID cannot change, so there's no use to threadsafe-ing its access.
1342
1348
return _id;
@@ -1374,7 +1380,7 @@ namespace lacewing
1374
1380
{
1375
1381
relayclientinternal::channel &internal = *(relayclientinternal::channel *)internaltag;
1376
1382
auto end = internal.client.channels.end();
1377
-
1383
+
1378
1384
auto i = std::find_if(internal.client.channels.begin(), end,
1379
1385
[&](relayclientinternal::channel * &c) { return c->id == internal.id; });
1380
1386
return (i == end || ++i == end) ? nullptr : &(*i)->public_;
@@ -1385,7 +1391,7 @@ namespace lacewing
1385
1391
std::vector<relayclientinternal::channel *> &c = ((lacewing::relayclientinternal *)internaltag)->channels;
1386
1392
return (c.begin() == c.end()) ? nullptr : &(*c.begin())->public_;
1387
1393
}
1388
-
1394
+
1389
1395
relayclient::channel::peer * relayclient::channel::firstpeer() const
1390
1396
{
1391
1397
std::vector<relayclientinternal::peer *> &p = ((lacewing::relayclientinternal::channel *)internaltag)->peers;
@@ -1414,7 +1420,7 @@ namespace lacewing
1414
1420
lock.checkHoldsRead ();
1415
1421
return ((relayclientinternal *)internaltag)->channellist ;
1416
1422
}
1417
-
1423
+
1418
1424
#define autohandlerfunctions (pub, intern, handlername ) \
1419
1425
void pub::on##handlername(pub::handler_##handlername handler) \
1420
1426
{ ((intern *) internaltag)->handler_ ##handlername = handler; \
0 commit comments