@@ -45,9 +45,16 @@ PABotBase::PABotBase(
4545 , m_last_ack(current_time())
4646 , m_state(State::RUNNING)
4747 , m_error(false )
48- , m_retransmit_thread(run_with_catch, " PABotBase::retransmit_thread()" , [this ]{ retransmit_thread (); })
4948{
5049 set_sniffer (message_logger);
50+
51+ // We must initialize this last because it will trigger the lifetime
52+ // sanitizer if it beats it to construction.
53+ m_retransmit_thread = std::thread (
54+ run_with_catch,
55+ " PABotBase::retransmit_thread()" ,
56+ [this ]{ retransmit_thread (); }
57+ );
5158}
5259PABotBase::~PABotBase (){
5360 stop ();
@@ -57,7 +64,7 @@ PABotBase::~PABotBase(){
5764}
5865
5966size_t PABotBase::inflight_requests (){
60- m_sanitizer.check_usage ();
67+ auto scope_check = m_sanitizer.check_scope ();
6168
6269 // Must be called under m_state_lock.
6370
@@ -71,15 +78,15 @@ size_t PABotBase::inflight_requests(){
7178}
7279
7380void PABotBase::connect (){
74- m_sanitizer.check_usage ();
81+ auto scope_check = m_sanitizer.check_scope ();
7582
7683 pabb_MsgAckRequest response;
7784 issue_request_and_wait (
7885 Microcontroller::DeviceRequest_seqnum_reset (), nullptr
7986 ).convert <PABB_MSG_ACK_REQUEST>(logger (), response);
8087}
8188void PABotBase::stop (){
82- m_sanitizer.check_usage ();
89+ auto scope_check = m_sanitizer.check_scope ();
8390
8491 // Make sure only one thread can get in here.
8592 State expected = State::RUNNING;
@@ -95,7 +102,7 @@ void PABotBase::stop(){
95102 m_retransmit_thread.join ();
96103
97104 {
98- SpinLockGuard lg (m_state_lock, " PABotBase::stop()" );
105+ ReadSpinLock lg (m_state_lock, " PABotBase::stop()" );
99106
100107 // Send a stop request, but don't wait for a response that we may never
101108 // receive.
@@ -122,7 +129,7 @@ void PABotBase::set_queue_limit(size_t queue_limit){
122129}
123130
124131void PABotBase::wait_for_all_requests (const Cancellable* cancelled){
125- m_sanitizer.check_usage ();
132+ auto scope_check = m_sanitizer.check_scope ();
126133
127134 std::unique_lock<std::mutex> lg (m_sleep_lock);
128135 m_logger.log (" Waiting for all requests to finish..." , COLOR_DARKGREEN);
@@ -134,7 +141,7 @@ void PABotBase::wait_for_all_requests(const Cancellable* cancelled){
134141 throw InvalidConnectionStateException ();
135142 }
136143 {
137- SpinLockGuard lg1 (m_state_lock, " PABotBase::wait_for_all_requests()" );
144+ ReadSpinLock lg1 (m_state_lock, " PABotBase::wait_for_all_requests()" );
138145#if 0
139146 m_logger.log(
140147 "Waiting for all requests to finish... (Requests: " +
@@ -170,7 +177,7 @@ bool PABotBase::try_stop_all_commands(){
170177 cout << " -----------------------------------------------------------------------------------------" << endl;
171178#endif
172179
173- m_sanitizer.check_usage ();
180+ auto scope_check = m_sanitizer.check_scope ();
174181
175182 uint64_t seqnum = try_issue_request (nullptr , Microcontroller::DeviceRequest_request_stop (), true );
176183 if (seqnum != 0 ){
@@ -197,13 +204,13 @@ void PABotBase::stop_all_commands(){
197204 cout << " -----------------------------------------------------------------------------------------" << endl;
198205#endif
199206
200- m_sanitizer.check_usage ();
207+ auto scope_check = m_sanitizer.check_scope ();
201208
202209 uint64_t seqnum = issue_request (nullptr , Microcontroller::DeviceRequest_request_stop (), true );
203210 clear_all_active_commands (seqnum);
204211}
205212bool PABotBase::try_next_command_interrupt (){
206- m_sanitizer.check_usage ();
213+ auto scope_check = m_sanitizer.check_scope ();
207214
208215 uint64_t seqnum = try_issue_request (nullptr , Microcontroller::DeviceRequest_next_command_interrupt (), true );
209216 if (seqnum != 0 ){
@@ -214,17 +221,17 @@ bool PABotBase::try_next_command_interrupt(){
214221 }
215222}
216223void PABotBase::next_command_interrupt (){
217- m_sanitizer.check_usage ();
224+ auto scope_check = m_sanitizer.check_scope ();
218225
219226 uint64_t seqnum = issue_request (nullptr , Microcontroller::DeviceRequest_next_command_interrupt (), true );
220227 clear_all_active_commands (seqnum);
221228}
222229void PABotBase::clear_all_active_commands (uint64_t seqnum){
223- m_sanitizer.check_usage ();
230+ auto scope_check = m_sanitizer.check_scope ();
224231
225232 // Remove all commands at or before the specified seqnum.
226233 std::lock_guard<std::mutex> lg0 (m_sleep_lock);
227- SpinLockGuard lg1 (m_state_lock, " PABotBase::next_command_interrupt()" );
234+ WriteSpinLock lg1 (m_state_lock, " PABotBase::next_command_interrupt()" );
228235 m_logger.log (" Clearing all active commands... (Commands: " + std::to_string (m_pending_commands.size ()) + " )" , COLOR_DARKGREEN);
229236
230237// if (m_pending_commands.size() > 2){
@@ -247,7 +254,7 @@ void PABotBase::clear_all_active_commands(uint64_t seqnum){
247254}
248255template <typename Map>
249256uint64_t PABotBase::infer_full_seqnum (const Map& map, seqnum_t seqnum) const {
250- m_sanitizer.check_usage ();
257+ auto scope_check = m_sanitizer.check_scope ();
251258
252259 // The protocol uses a 32-bit seqnum that wraps around. For our purposes of
253260 // retransmits, we use a full 64-bit seqnum to maintain sorting order
@@ -274,7 +281,7 @@ uint64_t PABotBase::infer_full_seqnum(const Map& map, seqnum_t seqnum) const{
274281}
275282
276283uint64_t PABotBase::oldest_live_seqnum () const {
277- m_sanitizer.check_usage ();
284+ auto scope_check = m_sanitizer.check_scope ();
278285
279286 // Must call under state lock.
280287 uint64_t oldest = m_send_seq;
@@ -289,7 +296,7 @@ uint64_t PABotBase::oldest_live_seqnum() const{
289296
290297template <typename Params>
291298void PABotBase::process_ack_request (BotBaseMessage message){
292- m_sanitizer.check_usage ();
299+ auto scope_check = m_sanitizer.check_scope ();
293300
294301 if (message.body .size () != sizeof (Params)){
295302 m_sniffer->log (" Ignoring message with invalid size." );
@@ -300,7 +307,7 @@ void PABotBase::process_ack_request(BotBaseMessage message){
300307
301308 AckState state;
302309 {
303- SpinLockGuard lg (m_state_lock, " PABotBase::process_ack_request()" );
310+ WriteSpinLock lg (m_state_lock, " PABotBase::process_ack_request()" );
304311
305312 if (m_pending_requests.empty ()){
306313 m_sniffer->log (" Unexpected request ack message: seqnum = " + std::to_string (seqnum));
@@ -345,7 +352,7 @@ void PABotBase::process_ack_request(BotBaseMessage message){
345352}
346353template <typename Params>
347354void PABotBase::process_ack_command (BotBaseMessage message){
348- m_sanitizer.check_usage ();
355+ auto scope_check = m_sanitizer.check_scope ();
349356
350357 if (message.body .size () != sizeof (Params)){
351358 m_sniffer->log (" Ignoring message with invalid size." );
@@ -354,7 +361,7 @@ void PABotBase::process_ack_command(BotBaseMessage message){
354361 const Params* params = (const Params*)message.body .c_str ();
355362 seqnum_t seqnum = params->seqnum ;
356363
357- SpinLockGuard lg (m_state_lock, " PABotBase::process_ack_command()" );
364+ WriteSpinLock lg (m_state_lock, " PABotBase::process_ack_command()" );
358365
359366 if (m_pending_commands.empty ()){
360367 m_sniffer->log (" Unexpected command ack message: seqnum = " + std::to_string (seqnum));
@@ -387,7 +394,7 @@ void PABotBase::process_ack_command(BotBaseMessage message){
387394}
388395template <typename Params>
389396void PABotBase::process_command_finished (BotBaseMessage message){
390- m_sanitizer.check_usage ();
397+ auto scope_check = m_sanitizer.check_scope ();
391398
392399 if (message.body .size () != sizeof (Params)){
393400 m_sniffer->log (" Ignoring message with invalid size." );
@@ -403,7 +410,7 @@ void PABotBase::process_command_finished(BotBaseMessage message){
403410// m_send_queue.emplace_back((uint8_t)PABB_MSG_ACK, std::string((char*)&ack, sizeof(ack)));
404411
405412 std::lock_guard<std::mutex> lg0 (m_sleep_lock);
406- SpinLockGuard lg1 (m_state_lock, " PABotBase::process_command_finished() - 0" );
413+ WriteSpinLock lg1 (m_state_lock, " PABotBase::process_command_finished() - 0" );
407414
408415 send_message (BotBaseMessage (PABB_MSG_ACK_REQUEST, std::string ((char *)&ack, sizeof (ack))), false );
409416
@@ -442,7 +449,7 @@ void PABotBase::process_command_finished(BotBaseMessage message){
442449 }
443450}
444451void PABotBase::on_recv_message (BotBaseMessage message){
445- m_sanitizer.check_usage ();
452+ auto scope_check = m_sanitizer.check_scope ();
446453
447454 switch (message.type ){
448455 case PABB_MSG_ACK_COMMAND:
@@ -495,7 +502,7 @@ void PABotBase::on_recv_message(BotBaseMessage message){
495502}
496503
497504void PABotBase::retransmit_thread (){
498- m_sanitizer.check_usage ();
505+ auto scope_check = m_sanitizer.check_scope ();
499506
500507// cout << "retransmit_thread()" << endl;
501508 auto last_sent = current_time ();
@@ -515,7 +522,7 @@ void PABotBase::retransmit_thread(){
515522 }
516523
517524 // Process retransmits.
518- SpinLockGuard lg (m_state_lock, " PABotBase::retransmit_thread()" );
525+ WriteSpinLock lg (m_state_lock, " PABotBase::retransmit_thread()" );
519526// std::cout << "retransmit_thread - m_pending_messages.size(): " << m_pending_messages.size() << std::endl;
520527// cout << "m_pending_messages.size()" << endl;
521528
@@ -550,7 +557,7 @@ uint64_t PABotBase::try_issue_request(
550557 const Cancellable* cancelled,
551558 const BotBaseRequest& request, bool silent_remove
552559){
553- m_sanitizer.check_usage ();
560+ auto scope_check = m_sanitizer.check_scope ();
554561
555562 BotBaseMessage message = request.message ();
556563 if (message.body .size () < sizeof (uint32_t )){
@@ -560,7 +567,7 @@ uint64_t PABotBase::try_issue_request(
560567 throw InternalProgramError (&m_logger, PA_CURRENT_FUNCTION, " Message is too long." );
561568 }
562569
563- SpinLockGuard lg (m_state_lock, " PABotBase::try_issue_request()" );
570+ WriteSpinLock lg (m_state_lock, " PABotBase::try_issue_request()" );
564571 if (cancelled != nullptr && cancelled->cancelled ()){
565572 throw OperationCancelledException ();
566573 }
@@ -615,7 +622,7 @@ uint64_t PABotBase::try_issue_command(
615622 const Cancellable* cancelled,
616623 const BotBaseRequest& request, bool silent_remove
617624){
618- m_sanitizer.check_usage ();
625+ auto scope_check = m_sanitizer.check_scope ();
619626
620627 BotBaseMessage message = request.message ();
621628 if (message.body .size () < sizeof (uint32_t )){
@@ -625,7 +632,7 @@ uint64_t PABotBase::try_issue_command(
625632 throw InternalProgramError (&m_logger, PA_CURRENT_FUNCTION, " Message is too long." );
626633 }
627634
628- SpinLockGuard lg (m_state_lock, " PABotBase::try_issue_command()" );
635+ WriteSpinLock lg (m_state_lock, " PABotBase::try_issue_command()" );
629636 if (cancelled != nullptr && cancelled->cancelled ()){
630637 throw OperationCancelledException ();
631638 }
@@ -686,7 +693,7 @@ uint64_t PABotBase::issue_request(
686693 const Cancellable* cancelled,
687694 const BotBaseRequest& request, bool silent_remove
688695){
689- m_sanitizer.check_usage ();
696+ auto scope_check = m_sanitizer.check_scope ();
690697
691698 // Issue a request or a command and return.
692699 //
@@ -728,7 +735,7 @@ uint64_t PABotBase::issue_command(
728735 const Cancellable* cancelled,
729736 const BotBaseRequest& request, bool silent_remove
730737){
731- m_sanitizer.check_usage ();
738+ auto scope_check = m_sanitizer.check_scope ();
732739
733740 // Issue a request or a command and return.
734741 //
@@ -771,7 +778,7 @@ bool PABotBase::try_issue_request(
771778 const BotBaseRequest& request,
772779 const Cancellable* cancelled
773780){
774- m_sanitizer.check_usage ();
781+ auto scope_check = m_sanitizer.check_scope ();
775782
776783 if (!request.is_command ()){
777784 return try_issue_request (cancelled, request, true ) != 0 ;
@@ -783,7 +790,7 @@ void PABotBase::issue_request(
783790 const BotBaseRequest& request,
784791 const Cancellable* cancelled
785792){
786- m_sanitizer.check_usage ();
793+ auto scope_check = m_sanitizer.check_scope ();
787794
788795 if (!request.is_command ()){
789796 issue_request (cancelled, request, true );
@@ -796,7 +803,7 @@ BotBaseMessage PABotBase::issue_request_and_wait(
796803 const BotBaseRequest& request,
797804 const Cancellable* cancelled
798805){
799- m_sanitizer.check_usage ();
806+ auto scope_check = m_sanitizer.check_scope ();
800807
801808 if (request.is_command ()){
802809 throw InternalProgramError (&m_logger, PA_CURRENT_FUNCTION, " This function only supports requests." );
@@ -806,12 +813,12 @@ BotBaseMessage PABotBase::issue_request_and_wait(
806813 return wait_for_request (seqnum);
807814}
808815BotBaseMessage PABotBase::wait_for_request (uint64_t seqnum){
809- m_sanitizer.check_usage ();
816+ auto scope_check = m_sanitizer.check_scope ();
810817
811818 std::unique_lock<std::mutex> lg (m_sleep_lock);
812819 while (true ){
813820 {
814- SpinLockGuard slg (m_state_lock, " PABotBase::issue_request_and_wait()" );
821+ WriteSpinLock slg (m_state_lock, " PABotBase::issue_request_and_wait()" );
815822 auto iter = m_pending_requests.find (seqnum);
816823 if (iter == m_pending_requests.end ()){
817824 throw OperationCancelledException ();
0 commit comments