Always keep break stack filled in tasks in threads

This commit is contained in:
Florian Märkl 2018-07-21 15:21:50 +02:00
parent 41127c0dfc
commit 7995089d3f
3 changed files with 59 additions and 38 deletions

View File

@ -213,48 +213,59 @@ R_API void r_cons_break_clear() {
I.context->breaked = false;
}
R_API void r_cons_break_push(RConsBreak cb, void *user) {
if (I.context->break_stack) {
//if we don't have any element in the stack start the signal
RConsBreakStack *b = R_NEW0 (RConsBreakStack);
if (!b) return;
if (r_stack_is_empty (I.context->break_stack)) {
R_API void r_cons_context_break_push(RConsContext *context, RConsBreak cb, void *user, bool sig) {
if (!context->break_stack) {
return;
}
//if we don't have any element in the stack start the signal
RConsBreakStack *b = R_NEW0 (RConsBreakStack);
if (!b) return;
if (r_stack_is_empty (context->break_stack)) {
#if __UNIX__ || __CYGWIN__
if (r_cons_context_is_main ()) {
signal (SIGINT, break_signal);
}
#endif
I.context->breaked = false;
if (sig && r_cons_context_is_main ()) {
signal (SIGINT, break_signal);
}
//save the actual state
b->event_interrupt = I.context->event_interrupt;
b->event_interrupt_data = I.context->event_interrupt_data;
r_stack_push (I.context->break_stack, b);
//configure break
I.context->event_interrupt = cb;
I.context->event_interrupt_data = user;
#endif
context->breaked = false;
}
//save the actual state
b->event_interrupt = context->event_interrupt;
b->event_interrupt_data = context->event_interrupt_data;
r_stack_push (context->break_stack, b);
//configure break
context->event_interrupt = cb;
context->event_interrupt_data = user;
}
R_API void r_cons_context_break_pop(RConsContext *context, bool sig) {
if (!context->break_stack) {
return;
}
//restore old state
RConsBreakStack *b = NULL;
b = r_stack_pop (context->break_stack);
if (b) {
context->event_interrupt = b->event_interrupt;
context->event_interrupt_data = b->event_interrupt_data;
break_stack_free (b);
} else {
//there is not more elements in the stack
#if __UNIX__ || __CYGWIN__
if (sig && r_cons_context_is_main ()) {
signal (SIGINT, SIG_IGN);
}
#endif
context->breaked = false;
}
}
R_API void r_cons_break_push(RConsBreak cb, void *user) {
r_cons_context_break_push (I.context, cb, user, true);
}
R_API void r_cons_break_pop() {
//restore old state
if (I.context->break_stack) {
RConsBreakStack *b = NULL;
b = r_stack_pop (I.context->break_stack);
if (b) {
I.context->event_interrupt = b->event_interrupt;
I.context->event_interrupt_data = b->event_interrupt_data;
break_stack_free (b);
} else {
//there is not more elements in the stack
#if __UNIX__ || __CYGWIN__
if (r_cons_context_is_main ()) {
signal (SIGINT, SIG_IGN);
}
#endif
I.context->breaked = false;
}
}
r_cons_context_break_pop (I.context, true);
}
R_API bool r_cons_is_breaked() {

View File

@ -331,7 +331,12 @@ static int task_run(RCoreTask *task) {
}
static int task_run_thread(RThread *th) {
return task_run (th->user);
RCoreTask *task = (RCoreTask *)th->user;
int ret = task_run (task);
if (task->cons_context && task->cons_context->break_stack) {
r_cons_context_break_pop (task->cons_context, false);
}
return ret;
}
R_API void r_core_task_enqueue(RCore *core, RCoreTask *task) {
@ -346,6 +351,9 @@ R_API void r_core_task_enqueue(RCore *core, RCoreTask *task) {
if (task->running_sem) {
r_th_sem_wait (task->running_sem);
}
if (task->cons_context) {
r_cons_context_break_push (task->cons_context, NULL, NULL, false);
}
r_list_append (core->tasks, task);
task->thread = r_th_new (task_run_thread, task, 0);
tasks_lock_leave (core, &old_sigset);

View File

@ -668,8 +668,10 @@ R_API void r_cons_context_load(RConsContext *context);
R_API void r_cons_context_reset();
R_API bool r_cons_context_is_main();
R_API void r_cons_context_break(RConsContext *context);
R_API void r_cons_context_break_push(RConsContext *context, RConsBreak cb, void *user, bool sig);
R_API void r_cons_context_break_pop(RConsContext *context, bool sig);
R_API void r_cons_break_push(RConsBreak cb, void *user);
R_API void r_cons_break_pop(void);
R_API void r_cons_break_push(RConsBreak cb, void*user);
R_API void r_cons_break_clear(void);
/* control */