@@ -63,6 +63,10 @@ bool areKeysSequential(const std::map<uint_fast16_t, T> &inputMap) {
63
63
return true ; // All keys are sequential
64
64
}
65
65
66
+ // Define static members
67
+ std::unordered_map<void *, std::weak_ptr<Server>> Server::instanceMap;
68
+ std::mutex Server::instanceMapMutex;
69
+
66
70
Server::Server (const std::string &bind_ip, const std::uint_fast16_t tcp_port,
67
71
const std::uint_fast16_t tick_rate_ms,
68
72
const std::uint_fast16_t select_timeout_ms,
@@ -103,35 +107,51 @@ Server::Server(const std::string &bind_ip, const std::uint_fast16_t tcp_port,
103
107
param->t2 = 1 ; // acknowledgement interval
104
108
105
109
// Function pointers for custom handler functions
110
+ void *key = static_cast <void *>(this );
106
111
CS104_Slave_setConnectionRequestHandler (
107
- slave, &Server::connectionRequestHandler, this );
112
+ slave, &Server::connectionRequestHandler, key );
108
113
CS104_Slave_setConnectionEventHandler (slave, &Server::connectionEventHandler,
109
- this );
110
- CS104_Slave_setRawMessageHandler (slave, &Server::rawMessageHandler, this );
114
+ key );
115
+ CS104_Slave_setRawMessageHandler (slave, &Server::rawMessageHandler, key );
111
116
CS104_Slave_setInterrogationHandler (slave, &Server::interrogationHandler,
112
- this );
117
+ key );
113
118
CS104_Slave_setCounterInterrogationHandler (
114
- slave, &Server::counterInterrogationHandler, this );
115
- // CS104_Slave_setClockSyncHandler(slave, &Server::clockSyncHandler, this);
116
- CS104_Slave_setReadHandler (slave, &Server::readHandler, this );
117
- CS104_Slave_setASDUHandler (slave, &Server::asduHandler, this );
119
+ slave, &Server::counterInterrogationHandler, key);
120
+ CS104_Slave_setReadHandler (slave, &Server::readHandler, key);
121
+ CS104_Slave_setASDUHandler (slave, &Server::asduHandler, key);
118
122
119
123
DEBUG_PRINT (Debug::Server, " Created" );
120
124
}
121
125
122
126
Server::~Server () {
123
127
// stops and destroys the slave
124
128
stop ();
125
- CS104_Slave_destroy (slave);
126
129
127
130
{
128
131
std::lock_guard<Module::GilAwareMutex> const st_lock (station_mutex);
129
132
stations.clear ();
130
133
}
131
134
135
+ {
136
+ std::lock_guard<std::mutex> lock (instanceMapMutex);
137
+ instanceMap.erase (
138
+ static_cast <void *>(this )); // Remove from map on destruction
139
+ }
140
+
141
+ CS104_Slave_destroy (slave);
142
+
132
143
DEBUG_PRINT (Debug::Server, " Removed" );
133
144
}
134
145
146
+ std::shared_ptr<Server> Server::getInstance (void *key) {
147
+ std::lock_guard<std::mutex> lock (instanceMapMutex);
148
+ auto it = instanceMap.find (key);
149
+ if (it != instanceMap.end ()) {
150
+ return it->second .lock ();
151
+ }
152
+ return {nullptr };
153
+ }
154
+
135
155
std::string Server::getIP () const { return ip; }
136
156
137
157
std::uint_fast16_t Server::getPort () const { return port; }
@@ -782,11 +802,8 @@ void Server::setOnConnectCallback(py::object &callable) {
782
802
std::uint_fast16_t Server::getTickRate_ms () const { return tickRate_ms; }
783
803
784
804
bool Server::connectionRequestHandler (void *parameter, const char *ipAddress) {
785
- std::shared_ptr<Server> instance{};
786
-
787
- try {
788
- instance = static_cast <Server *>(parameter)->shared_from_this ();
789
- } catch (const std::bad_weak_ptr &e) {
805
+ const auto instance = getInstance (parameter);
806
+ if (!instance) {
790
807
DEBUG_PRINT (Debug::Server, " Reject connection request in shutdown" );
791
808
return false ;
792
809
}
@@ -818,11 +835,8 @@ void Server::connectionEventHandler(void *parameter,
818
835
begin = std::chrono::steady_clock::now ();
819
836
}
820
837
821
- std::shared_ptr<Server> instance{};
822
-
823
- try {
824
- instance = static_cast <Server *>(parameter)->shared_from_this ();
825
- } catch (const std::bad_weak_ptr &e) {
838
+ const auto instance = getInstance (parameter);
839
+ if (!instance) {
826
840
DEBUG_PRINT (Debug::Server, " Ignore connection event " +
827
841
PeerConnectionEvent_toString (event) +
828
842
" in shutdown" );
@@ -1259,11 +1273,8 @@ Server::getValidMessage(IMasterConnection connection, CS101_ASDU asdu) {
1259
1273
1260
1274
void Server::rawMessageHandler (void *parameter, IMasterConnection connection,
1261
1275
uint_fast8_t *msg, int msgSize, bool sent) {
1262
- std::shared_ptr<Server> instance{};
1263
-
1264
- try {
1265
- instance = static_cast <Server *>(parameter)->shared_from_this ();
1266
- } catch (const std::bad_weak_ptr &e) {
1276
+ const auto instance = getInstance (parameter);
1277
+ if (!instance) {
1267
1278
DEBUG_PRINT (Debug::Server, " Ignore raw message in shutdown" );
1268
1279
return ;
1269
1280
}
@@ -1284,11 +1295,8 @@ bool Server::interrogationHandler(void *parameter, IMasterConnection connection,
1284
1295
begin = std::chrono::steady_clock::now ();
1285
1296
}
1286
1297
1287
- std::shared_ptr<Server> instance{};
1288
-
1289
- try {
1290
- instance = static_cast <Server *>(parameter)->shared_from_this ();
1291
- } catch (const std::bad_weak_ptr &e) {
1298
+ const auto instance = getInstance (parameter);
1299
+ if (!instance) {
1292
1300
DEBUG_PRINT (Debug::Server, " Reject interrogation command in shutdown" );
1293
1301
return false ;
1294
1302
}
@@ -1381,11 +1389,8 @@ bool Server::counterInterrogationHandler(void *parameter,
1381
1389
begin = std::chrono::steady_clock::now ();
1382
1390
}
1383
1391
1384
- std::shared_ptr<Server> instance{};
1385
-
1386
- try {
1387
- instance = static_cast <Server *>(parameter)->shared_from_this ();
1388
- } catch (const std::bad_weak_ptr &e) {
1392
+ const auto instance = getInstance (parameter);
1393
+ if (!instance) {
1389
1394
DEBUG_PRINT (Debug::Server,
1390
1395
" Reject counter interrogation command in shutdown" );
1391
1396
return false ;
@@ -1482,11 +1487,8 @@ bool Server::readHandler(void *parameter, IMasterConnection connection,
1482
1487
begin = std::chrono::steady_clock::now ();
1483
1488
}
1484
1489
1485
- std::shared_ptr<Server> instance{};
1486
-
1487
- try {
1488
- instance = static_cast <Server *>(parameter)->shared_from_this ();
1489
- } catch (const std::bad_weak_ptr &e) {
1490
+ const auto instance = getInstance (parameter);
1491
+ if (!instance) {
1490
1492
DEBUG_PRINT (Debug::Server, " Reject read command in shutdown" );
1491
1493
return false ;
1492
1494
}
@@ -1562,11 +1564,8 @@ bool Server::asduHandler(void *parameter, IMasterConnection connection,
1562
1564
begin = std::chrono::steady_clock::now ();
1563
1565
}
1564
1566
1565
- std::shared_ptr<Server> instance{};
1566
-
1567
- try {
1568
- instance = static_cast <Server *>(parameter)->shared_from_this ();
1569
- } catch (const std::bad_weak_ptr &e) {
1567
+ const auto instance = getInstance (parameter);
1568
+ if (!instance) {
1570
1569
DEBUG_PRINT (Debug::Server, " Reject asdu in shutdown" );
1571
1570
return false ;
1572
1571
}
0 commit comments