#include <fcntl.h>
#include <unistd.h>
-
+static pthread_mutex_t stop_all_mutex = PTHREAD_MUTEX_INITIALIZER;
void inline free_msg(struct msg_t *msg)
{
return res;
}
-enum ErrorCode stop_all(void)
+
+enum ErrorCode stop_all_no_lock(void)
{
enum ErrorCode error_code = ERR_NO;
struct msg_t *msg;
- LOGI("entry\n");
-
// stop all only if it has not been called yet
if (check_running_status(&prof_session)) {
msg = gen_stop_msg();
LOGI("finished: ret = %d\n", error_code);
return error_code;
}
+
+int stop_all_in_process(void)
+{
+ return (pthread_mutex_trylock(&stop_all_mutex) != 0);
+}
+
+void stop_all_done(void)
+{
+ pthread_mutex_unlock(&stop_all_mutex);
+}
+
+enum ErrorCode stop_all(void)
+{
+ enum ErrorCode error_code = ERR_NO;
+
+ pthread_mutex_lock(&stop_all_mutex);
+ error_code = stop_all_no_lock();
+ pthread_mutex_unlock(&stop_all_mutex);
+
+ return error_code;
+}
+
struct binary_ack {
uint32_t type;
char *binpath;
free(ba->binpath);
free(ba);
}
+
static size_t binary_ack_size(const struct binary_ack *ba)
{
/* MD5 is 16 bytes, so 16*2 hex digits */
void free_sys_info(struct system_info_t *sys_info);
int start_replay(void);
void stop_replay(void);
+
enum ErrorCode stop_all(void);
+enum ErrorCode stop_all_no_lock(void);
+int stop_all_in_process(void);
+void stop_all_done(void);
void reset_msg(struct msg_t *msg);
void reset_replay_event_seq(struct replay_event_seq_t *res);
// wait for all other thread exit
for (i = 0; i < MAX_TARGET_COUNT; i++) {
if (manager.target[i].recv_thread != -1) {
+ LOGI("join recv thread [%d] is started\n", i);
pthread_join(manager.target[i].recv_thread, NULL);
+ LOGI("join recv thread %d. done\n", i);
}
}
}
static void terminate(int sig)
{
- _unlink_files();
- _close_server_socket();
- exit_buf();
- remove_buf_modules();
- if (sig != 0) {
- LOGW("Terminating due signal %s\n", strsignal(sig));
- signal(sig, SIG_DFL);
- raise(sig);
+ LOGI("terminate! sig = %d\n", sig);
+ if (!stop_all_in_process()) {
+ // we are up there if signal accept and stop_all func was not
+ // called yet.
+
+ // so we need stop_all firstly (if profiling was
+ // not started it will be dummy call) and release other sources
+ stop_all_no_lock();
+ _unlink_files();
+ _close_server_socket();
+ exit_buf();
+ remove_buf_modules();
+ if (sig != 0) {
+ LOGW("Terminating due signal %s\n", strsignal(sig));
+ signal(sig, SIG_DFL);
+ raise(sig);
+ }
+ stop_all_done();
+ } else {
+ // we are there if stop_all function was called by some reasons
+
+ // if stop_all called we cannot call remove_buf_modules and
+ // other funcs because of threads are not stopped yet
+ LOGW("Stop in progress\n");
+ if (sig != 0) {
+ LOGW("ignore signal %s\n", strsignal(sig));
+ signal(sig, SIG_IGN);
+ }
}
}
setitimer(ITIMER_REAL, &stopval, NULL);
pthread_kill(manager.sampling_thread, SIGUSR1);
+ LOGI("join sampling thread started\n");
pthread_join(manager.sampling_thread, NULL);
+ LOGI("join sampling thread done\n");
manager.sampling_thread = -1;
}