|
19 | 19 | namespace Modbus { |
20 | 20 | namespace TCP { |
21 | 21 |
|
| 22 | +//* maximum number of Modbus registers (per type) |
22 | 23 | static constexpr int MAX_REGS = 0x10000; |
23 | 24 |
|
| 25 | +//* value to increment error counter if semaphore could not be acquired |
| 26 | +static constexpr long SEMAPHORE_ERROR_INC = 10; |
| 27 | + |
| 28 | +//* value to decrement error counter if semaphore could be acquired |
| 29 | +static constexpr long SEMAPHORE_ERROR_DEC = 1; |
| 30 | + |
| 31 | +//* maximum value of semaphore error counter |
| 32 | +static constexpr long SEMAPHORE_ERROR_MAX = 1000; |
| 33 | + |
24 | 34 | //* maximum time to wait for semaphore (100ms) |
25 | 35 | static constexpr struct timespec SEMAPHORE_MAX_TIME = {0, 100'000}; |
26 | 36 |
|
@@ -379,10 +389,24 @@ Client_Poll::run_t Client_Poll::run(int signal_fd, bool reconnect, int timeout) |
379 | 389 |
|
380 | 390 | // handle request |
381 | 391 | if (semaphore) { |
382 | | - if (!semaphore->wait(SEMAPHORE_MAX_TIME)) |
| 392 | + if (!semaphore->wait(SEMAPHORE_MAX_TIME)) { |
383 | 393 | std::cerr << Print_Time::iso << " WARNING: Failed to acquire semaphore '" |
384 | 394 | << semaphore->get_name() << "' within 100ms." << std::endl; |
| 395 | + |
| 396 | + semaphore_error_counter += SEMAPHORE_ERROR_INC; |
| 397 | + |
| 398 | + if (semaphore_error_counter >= SEMAPHORE_ERROR_MAX) { |
| 399 | + std::cerr << Print_Time::iso << "ERROR: Repeatedly failed to acquire the semaphore" |
| 400 | + << std::endl; |
| 401 | + close_con(client_addrs); |
| 402 | + return run_t::semaphore; |
| 403 | + } |
| 404 | + } else { |
| 405 | + semaphore_error_counter -= SEMAPHORE_ERROR_DEC; |
| 406 | + if (semaphore_error_counter < 0) semaphore_error_counter = 0; |
| 407 | + } |
385 | 408 | } |
| 409 | + |
386 | 410 | int ret = modbus_reply(modbus, query, rc, mapping); |
387 | 411 | if (semaphore && semaphore->is_acquired()) semaphore->post(); |
388 | 412 |
|
|
0 commit comments