84 lines
1.9 KiB
C
84 lines
1.9 KiB
C
|
#include "intr.h"
|
||
|
|
||
|
#include "util/log.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
|
||
|
bool
|
||
|
sc_intr_init(struct sc_intr *intr) {
|
||
|
bool ok = sc_mutex_init(&intr->mutex);
|
||
|
if (!ok) {
|
||
|
LOGE("Could not init intr mutex");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
intr->socket = SC_INVALID_SOCKET;
|
||
|
intr->process = SC_PROCESS_NONE;
|
||
|
|
||
|
atomic_store_explicit(&intr->interrupted, false, memory_order_relaxed);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
sc_intr_set_socket(struct sc_intr *intr, sc_socket socket) {
|
||
|
assert(intr->process == SC_PROCESS_NONE);
|
||
|
|
||
|
sc_mutex_lock(&intr->mutex);
|
||
|
bool interrupted =
|
||
|
atomic_load_explicit(&intr->interrupted, memory_order_relaxed);
|
||
|
if (!interrupted) {
|
||
|
intr->socket = socket;
|
||
|
}
|
||
|
sc_mutex_unlock(&intr->mutex);
|
||
|
|
||
|
return !interrupted;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
sc_intr_set_process(struct sc_intr *intr, sc_pid pid) {
|
||
|
assert(intr->socket == SC_INVALID_SOCKET);
|
||
|
|
||
|
sc_mutex_lock(&intr->mutex);
|
||
|
bool interrupted =
|
||
|
atomic_load_explicit(&intr->interrupted, memory_order_relaxed);
|
||
|
if (!interrupted) {
|
||
|
intr->process = pid;
|
||
|
}
|
||
|
sc_mutex_unlock(&intr->mutex);
|
||
|
|
||
|
return !interrupted;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
sc_intr_interrupt(struct sc_intr *intr) {
|
||
|
sc_mutex_lock(&intr->mutex);
|
||
|
|
||
|
atomic_store_explicit(&intr->interrupted, true, memory_order_relaxed);
|
||
|
|
||
|
// No more than one component to interrupt
|
||
|
assert(intr->socket == SC_INVALID_SOCKET ||
|
||
|
intr->process == SC_PROCESS_NONE);
|
||
|
|
||
|
if (intr->socket != SC_INVALID_SOCKET) {
|
||
|
LOGD("Interrupting socket");
|
||
|
net_interrupt(intr->socket);
|
||
|
intr->socket = SC_INVALID_SOCKET;
|
||
|
}
|
||
|
if (intr->process != SC_PROCESS_NONE) {
|
||
|
LOGD("Interrupting process");
|
||
|
sc_process_terminate(intr->process);
|
||
|
intr->process = SC_PROCESS_NONE;
|
||
|
}
|
||
|
|
||
|
sc_mutex_unlock(&intr->mutex);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
sc_intr_destroy(struct sc_intr *intr) {
|
||
|
assert(intr->socket == SC_INVALID_SOCKET);
|
||
|
assert(intr->process == SC_PROCESS_NONE);
|
||
|
|
||
|
sc_mutex_destroy(&intr->mutex);
|
||
|
}
|