@@ -159,7 +159,7 @@ namespace lacewing
159159 std::shared_ptr<relayclient::channel> relayclientinternal::findchannelbyid (unsigned short id)
160160 {
161161 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 (),
163163 [&](const std::shared_ptr<const relayclient::channel> &c) { return c->id () == id; });
164164 return i == channels.cend () ? nullptr : *i;
165165 }
@@ -170,7 +170,7 @@ namespace lacewing
170170
171171 /* opening 0 byte */
172172 socket->write (" " , 1 );
173-
173+
174174 // internal.udp->host(socket->server_address(), nullptr, 0U);
175175
176176 framebuilder &message = internal.message ;
@@ -211,7 +211,7 @@ namespace lacewing
211211 char * dataCpy = (char *)malloc (size);
212212 if (!dataCpy)
213213 throw std::exception (" Out of memory." );
214-
214+
215215 memcpy (dataCpy, data, size);
216216
217217 internal.reader .process (dataCpy, size);
@@ -364,7 +364,7 @@ namespace lacewing
364364 void relayclient::join (std::string_view channelName, bool hidden, bool autoclose)
365365 {
366366 relayclientinternal &internal = *((relayclientinternal *)internaltag);
367-
367+
368368 if (name ().empty ())
369369 {
370370 error error = lacewing::error_new ();
@@ -541,7 +541,7 @@ namespace lacewing
541541 lacewing::readlock rl = lock.createReadLock ();
542542 return _id;
543543 }
544-
544+
545545 std::string relayclient::channel::peer::name () const
546546 {
547547 lacewing::readlock rl = lock.createReadLock ();
@@ -559,14 +559,14 @@ namespace lacewing
559559 // Atomic, no point changing it
560560 return _readonly;
561561 }
562-
562+
563563 size_t relayclient::channelcount () const
564564 {
565565 lacewing::readlock rl = lock.createReadLock ();
566566 return ((relayclientinternal *)internaltag)->channels .size ();
567567 }
568568
569- int relayclient::id () const
569+ lw_ui16 relayclient::id () const
570570 {
571571 lacewing::readlock rl = lock.createReadLock ();
572572 return ((relayclientinternal *)internaltag)->id ;
@@ -587,8 +587,8 @@ namespace lacewing
587587
588588 bool relayclientinternal::messagehandler (unsigned char type, const char * message, size_t size, bool blasted)
589589 {
590- unsigned char messagetypeid = (type >> 4 );
591- unsigned char variant = (type << 4 );
590+ lw_ui8 messagetypeid = (type >> 4 );
591+ lw_ui8 variant = (type << 4 );
592592
593593 variant >>= 4 ;
594594
@@ -598,8 +598,8 @@ namespace lacewing
598598 {
599599 case 0 : /* response */
600600 {
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 ;
603603
604604 if (reader.failed )
605605 break ;
@@ -610,14 +610,14 @@ namespace lacewing
610610 {
611611 if (succeeded)
612612 {
613- id = reader.get <unsigned short >();
613+ id = reader.get <lw_ui16 >();
614614
615615 // Don't expect welcome message to be null terminated
616616 std::string_view welcomemessage = reader.get (reader.bytesleft ());
617617
618618 if (reader.failed )
619619 break ;
620-
620+
621621 this ->welcomemessage = welcomemessage;
622622
623623 socket->server_address ()->resolve ();
@@ -712,16 +712,16 @@ namespace lacewing
712712
713713 auto channel = std::make_shared<relayclient::channel>(*this );
714714 auto channelWriteLock = channel->lock .createWriteLock ();
715-
715+
716716 channel->_id = channelid;
717717 channel->_name = name;
718718 channel->_ischannelmaster = (flags & 1 ) != 0 ;
719719
720720 for (; reader.bytesleft () > 0 ;)
721721 {
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 >();
725725 std::string_view name2 = reader.get (namelength2);
726726
727727 if (reader.failed )
@@ -781,7 +781,7 @@ namespace lacewing
781781
782782 if (handler_channel_leave)
783783 handler_channel_leave (client, channel);
784-
784+
785785 // Handler BEFORE finding it in channel list, in case leave handler calls disconnect.
786786 if (!connected)
787787 break ;
@@ -953,8 +953,8 @@ namespace lacewing
953953
954954 case 4 : /* binaryserverchannelmessage */
955955 {
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 >();
958958 if (reader.failed )
959959 break ;
960960
@@ -1033,7 +1033,7 @@ namespace lacewing
10331033
10341034 lw_ui8 flags = reader.get <lw_ui8>();
10351035 std::string_view name = reader.get (reader.bytesleft ()); // name's not null terminated
1036-
1036+
10371037 if (reader.failed )
10381038 {
10391039 /* no flags/name - the peer must have left the channel */
@@ -1044,9 +1044,12 @@ namespace lacewing
10441044 return true ;
10451045
10461046 peer->_readonly = true ;
1047+
1048+ channelWriteLock.lw_unlock (); // Don't leave it locked while handler is run
1049+
10471050 if (handler_peer_disconnect)
10481051 handler_peer_disconnect (client, channel2, peer);
1049-
1052+
10501053 channel2 = findchannelbyid (channel);
10511054
10521055 // Handler called disconnect, so channel is no longer accessible
@@ -1055,6 +1058,7 @@ namespace lacewing
10551058
10561059 // LW_ESCALATION_NOTE
10571060 // auto channelWriteLock = channelReadLock.lw_upgrade();
1061+ channelWriteLock.lw_relock ();
10581062 auto i = std::find_if (channel2->peers .begin (), channel2->peers .end (),
10591063 [=](std::shared_ptr<relayclient::channel::peer> &p) { return p->_id == peerid; });
10601064 if (i != channel2->peers .end ())
@@ -1074,6 +1078,8 @@ namespace lacewing
10741078
10751079 // this does channel2->peers.push_back()
10761080 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
10771083 }
10781084
10791085 if (handler_peer_connect)
@@ -1244,8 +1250,8 @@ namespace lacewing
12441250 // udphellotick just sends UDPHello every 0.5s, and is managed by the relayclientinternal::udphellotimer var.
12451251 // It starts from the time the Connect Request Success message is sent.
12461252 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+
12491255 message.addheader (7 , 0 , true , id); /* udphello */
12501256 message.send (udp, socket->server_address ());
12511257 }
@@ -1336,7 +1342,7 @@ namespace lacewing
13361342 return _ischannelmaster;
13371343 }
13381344
1339- unsigned short relayclient::channel::peer::id () const
1345+ lw_ui16 relayclient::channel::peer::id () const
13401346 {
13411347 // We won't check for read lock, as ID cannot change, so there's no use to threadsafe-ing its access.
13421348 return _id;
@@ -1374,7 +1380,7 @@ namespace lacewing
13741380 {
13751381 relayclientinternal::channel &internal = *(relayclientinternal::channel *)internaltag;
13761382 auto end = internal.client.channels.end();
1377-
1383+
13781384 auto i = std::find_if(internal.client.channels.begin(), end,
13791385 [&](relayclientinternal::channel * &c) { return c->id == internal.id; });
13801386 return (i == end || ++i == end) ? nullptr : &(*i)->public_;
@@ -1385,7 +1391,7 @@ namespace lacewing
13851391 std::vector<relayclientinternal::channel *> &c = ((lacewing::relayclientinternal *)internaltag)->channels;
13861392 return (c.begin() == c.end()) ? nullptr : &(*c.begin())->public_;
13871393 }
1388-
1394+
13891395 relayclient::channel::peer * relayclient::channel::firstpeer() const
13901396 {
13911397 std::vector<relayclientinternal::peer *> &p = ((lacewing::relayclientinternal::channel *)internaltag)->peers;
@@ -1414,7 +1420,7 @@ namespace lacewing
14141420 lock.checkHoldsRead ();
14151421 return ((relayclientinternal *)internaltag)->channellist ;
14161422 }
1417-
1423+
14181424#define autohandlerfunctions (pub, intern, handlername ) \
14191425 void pub::on##handlername(pub::handler_##handlername handler) \
14201426 { ((intern *) internaltag)->handler_ ##handlername = handler; \
0 commit comments