Skip to content

Commit eee24cb

Browse files
committed
Fixed deadlock on startup
1 parent 9212794 commit eee24cb

6 files changed

Lines changed: 45 additions & 29 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,6 @@ install(
9797

9898
IF (CAPIO_BUILD_TESTS)
9999
message(STATUS "Building CAPIO test suite")
100+
add_compile_definitions(CAPIO_BUILD_TESTS)
100101
add_subdirectory(tests)
101102
ENDIF (CAPIO_BUILD_TESTS)

src/posix/utils/requests.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,19 @@ inline void handshake_request(const long tid, const long pid, const std::string
5050
char req[CAPIO_REQ_MAX_SIZE];
5151
sprintf(req, "%04d %ld %ld %s", CAPIO_REQUEST_HANDSHAKE, tid, pid, app_name.c_str());
5252
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
53-
bufs_response->at(pid)->read();
53+
54+
#ifndef CAPIO_BUILD_TESTS
55+
/*
56+
* The handshake request must be blocking ONLY when not building tests. This is because when
57+
* starting unit tests, the binary is loaded with libcapio_posix.so underneath thus performing
58+
* a handshake request. If the handshake is blocking, then the capio_server binary cannot be
59+
* started as the whole process is waiting for a handshake.
60+
*/
61+
if (bufs_response->at(pid)->read() == 0) {
62+
ERR_EXIT("Error: handshake request sent while capio_server is shutting down!");
63+
}
64+
#endif
65+
5466
LOG("Sent handshake request");
5567
}
5668

src/server/client-manager/client_manager.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,7 @@ class ClientManager {
123123
return CAPIO_DEFAULT_APP_NAME;
124124
}
125125

126-
inline auto get_connected_posix_client() {
127-
return bufs_response->size();
128-
}
126+
inline auto get_connected_posix_client() { return bufs_response->size(); }
129127
};
130128

131129
inline ClientManager *client_manager;

src/server/client-manager/handlers/handshake.hpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,27 @@ inline void handshake_handler(const char *const str) {
1616
char app_name[1024];
1717
sscanf(str, "%d %d %s", &tid, &pid, app_name);
1818
START_LOG(gettid(), "call(tid=%ld, pid=%ld, app_name=%s)", tid, pid, app_name);
19-
if (termination_phase) {
20-
LOG("Termination phase is in progress. ignoring further handshakes.");
21-
return;
22-
}
19+
2320
client_manager->register_client(app_name, tid);
2421
storage_service->register_client(app_name, tid);
25-
// Unlock client waiting to start
26-
client_manager->reply_to_client(tid, 1);
22+
/*
23+
* The handshake request must be blocking ONLY when not building tests. This is because when
24+
* starting unit tests, the binary is loaded with libcapio_posix.so underneath thus performing
25+
* a handshake request. If the handshake is blocking, then the capio_server binary cannot be
26+
* started as the whole process is waiting for a handshake.
27+
*/
28+
#ifndef CAPIO_BUILD_TESTS
29+
// If not on termination phase, return 1. Otherwise, return 0
30+
// if - is returned posix application will terminate
31+
if (!termination_phase) {
32+
// Unlock client waiting to start
33+
LOG("Allowing handshake to continue");
34+
client_manager->reply_to_client(tid, 1);
35+
} else {
36+
LOG("Termination phase is in progress. ignoring further handshakes.");
37+
client_manager->reply_to_client(tid, 0);
38+
}
39+
#endif
2740
}
2841

2942
#endif // HANDSHAKE_HPP

src/server/client-manager/request_handler_engine.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,15 @@ class RequestHandlerEngine {
134134
if (termination_phase) {
135135
std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] "
136136
<< "Termination phase is in progress... Ignoring Exception likely "
137-
"thrown while "
138-
"reciving SIGUSR1"
137+
"thrown while receiving SIGUSR1"
139138
<< std::endl;
140139
continue;
141140
}
142141
throw e;
143142
}
144143

145144
if (code < 0 && errno == EINTR) {
146-
LOG("Signal recived while waiting on data. skipping iteration");
145+
LOG("Signal received while waiting on data. skipping iteration");
147146
continue;
148147
}
149148

src/server/utils/signals.hpp

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,14 @@ inline void sig_term_handler(int signum, siginfo_t *info, void *ptr) {
4646
exit(EXIT_SUCCESS);
4747
}
4848

49-
5049
inline void sig_usr1_handler(int signum, siginfo_t *info, void *ptr) {
5150
if (gettid() != CAPIO_SERVER_MAIN_PID) {
5251
return;
5352
}
5453
START_LOG(gettid(), "call(signal=[%d] (%s) from process with pid=%ld)", signum,
5554
strsignal(signum), info != nullptr ? info->si_pid : -1);
5655
std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] "
57-
<< "Recived request for graceful shutdown!" << std::endl;
56+
<< "Received request for graceful shutdown!" << std::endl;
5857
termination_phase = true;
5958
}
6059

@@ -67,28 +66,23 @@ inline void setup_signal_handlers() {
6766
static struct sigaction sigact, sigact_usr1;
6867
memset(&sigact, 0, sizeof(sigact));
6968
memset(&sigact, 0, sizeof(sigact_usr1));
70-
sigact.sa_sigaction = sig_term_handler;
71-
sigact.sa_flags = SA_SIGINFO;
69+
sigact.sa_sigaction = sig_term_handler;
70+
sigact.sa_flags = SA_SIGINFO;
7271
sigact_usr1.sa_sigaction = sig_usr1_handler;
7372
sigact_usr1.sa_flags = SA_SIGINFO;
74-
int res = sigaction(SIGTERM, &sigact, nullptr);
75-
res = res | sigaction(SIGILL, &sigact, nullptr);
76-
res = res | sigaction(SIGABRT, &sigact, nullptr);
77-
res = res | sigaction(SIGFPE, &sigact, nullptr);
78-
res = res | sigaction(SIGSEGV, &sigact, nullptr);
79-
res = res | sigaction(SIGQUIT, &sigact, nullptr);
80-
res = res | sigaction(SIGPIPE, &sigact, nullptr);
81-
res = res | sigaction(SIGINT, &sigact, nullptr);
82-
res = res | sigaction(SIGUSR1, &sigact_usr1, nullptr);
73+
int res = sigaction(SIGTERM, &sigact, nullptr) | sigaction(SIGILL, &sigact, nullptr) |
74+
sigaction(SIGABRT, &sigact, nullptr) | sigaction(SIGFPE, &sigact, nullptr) |
75+
sigaction(SIGSEGV, &sigact, nullptr) | sigaction(SIGQUIT, &sigact, nullptr) |
76+
sigaction(SIGPIPE, &sigact, nullptr) | sigaction(SIGINT, &sigact, nullptr) |
77+
sigaction(SIGUSR1, &sigact_usr1, nullptr);
8378
if (res == -1) {
8479
ERR_EXIT("sigaction for SIGTERM");
8580
}
8681
}
8782

88-
8983
/*
9084
* Defining here the RequestHandlerEngine::handle_termination_phase()
91-
* to avoid recursive include wihin the header files
85+
* to avoid recursive include within the header files
9286
*/
9387
inline void RequestHandlerEngine::handle_termination_phase() const {
9488
START_LOG(capio_syscall(SYS_gettid), "call()");
@@ -100,5 +94,4 @@ inline void RequestHandlerEngine::handle_termination_phase() const {
10094
sig_term_handler(SIGTERM, nullptr, nullptr);
10195
}
10296

103-
10497
#endif // CAPIO_SERVER_HANDLERS_SIGNALS_HPP

0 commit comments

Comments
 (0)