diff --git a/src/http/server.c b/src/http/server.c index c7d51b5..9f97613 100644 --- a/src/http/server.c +++ b/src/http/server.c @@ -50,6 +50,7 @@ #include "../tools.h" #include "../threading.h" #include "../logging.h" +#include "../process.h" #include "../picture.h" #include "../encoder.h" #include "../stream.h" @@ -176,6 +177,9 @@ int http_server_listen(struct http_server_t *server) { EXPOSED(expose_begin_ts) = get_now_monotonic(); EXPOSED(expose_cmp_ts) = EXPOSED(expose_begin_ts); EXPOSED(expose_end_ts) = EXPOSED(expose_begin_ts); + // See _http_exposed_refresh() + EXPOSED(notify_last_width) = EXPOSED(picture->width); + EXPOSED(notify_last_height) = EXPOSED(picture->height); # undef EXPOSED { @@ -791,6 +795,25 @@ static void _http_exposed_refresh(UNUSED int fd, UNUSED short what, void *v_serv # undef UNLOCK_STREAM _http_queue_send_stream(server, stream_updated, picture_updated); + +# define EXPOSED(_next) server->run->exposed->_next + + if ( + picture_updated + && server->notify_parent + && ( + EXPOSED(notify_last_online) != EXPOSED(online) + || EXPOSED(notify_last_width) != EXPOSED(picture->width) + || EXPOSED(notify_last_height) != EXPOSED(picture->height) + ) + ) { + EXPOSED(notify_last_online) = EXPOSED(online); + EXPOSED(notify_last_width) = EXPOSED(picture->width); + EXPOSED(notify_last_height) = EXPOSED(picture->height); + process_notify_parent(); + } + +# undef EXPOSED } static bool _expose_new_picture_unsafe(struct http_server_t *server) { diff --git a/src/http/server.h b/src/http/server.h index 5812e47..d26ecfc 100644 --- a/src/http/server.h +++ b/src/http/server.h @@ -65,6 +65,10 @@ struct exposed_t { long double expose_cmp_ts; long double expose_end_ts; long double last_as_blank_ts; + + bool notify_last_online; + unsigned notify_last_width; + unsigned notify_last_height; }; struct http_server_runtime_t { @@ -100,6 +104,8 @@ struct http_server_t { unsigned fake_width; unsigned fake_height; + bool notify_parent; + struct http_server_runtime_t *run; }; diff --git a/src/options.c b/src/options.c index 0c01725..1a6e398 100644 --- a/src/options.c +++ b/src/options.c @@ -110,6 +110,7 @@ enum _OPT_VALUES { #ifdef WITH_SETPROCTITLE _O_PROCESS_NAME_PREFIX, #endif + _O_NOTIFY_PARENT, _O_LOG_LEVEL, _O_PERF, @@ -180,6 +181,7 @@ static const struct option _LONG_OPTS[] = { #ifdef WITH_SETPROCTITLE {"process-name-prefix", required_argument, NULL, _O_PROCESS_NAME_PREFIX}, #endif + {"notify-parent", no_argument, NULL, _O_NOTIFY_PARENT}, {"log-level", required_argument, NULL, _O_LOG_LEVEL}, {"perf", no_argument, NULL, _O_PERF}, @@ -396,6 +398,7 @@ int options_parse(struct options_t *options, struct device_t *dev, struct encode # ifdef WITH_SETPROCTITLE case _O_PROCESS_NAME_PREFIX: OPT_SET(process_name_prefix, optarg); # endif + case _O_NOTIFY_PARENT: OPT_SET(server->notify_parent, true); case _O_LOG_LEVEL: OPT_NUMBER("--log-level", log_level, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, 0); case _O_PERF: OPT_SET(log_level, LOG_LEVEL_PERF); @@ -633,6 +636,8 @@ static void _help(struct device_t *dev, struct encoder_t *encoder, struct http_s #ifdef WITH_SETPROCTITLE printf(" --process-name-prefix ── Set process name prefix which will be displayed in the process list\n"); printf(" like ': ustreamer --blah-blah-blah'. Default: disabled.\n\n"); + printf(" --notify-parent ────────────── Send SIGUSR2 to the parent process when the stream parameters are changed.\n"); + printf(" Checking changes is performed for the online flag and image resolution.\n\n"); #endif printf("Logging options:\n"); printf("════════════════\n"); diff --git a/src/process.h b/src/process.h index 05a66cc..bfcc92f 100644 --- a/src/process.h +++ b/src/process.h @@ -22,6 +22,12 @@ #pragma once +#include +#include + +#include + + #if defined(__linux__) # define HAS_PDEATHSIG #elif defined(__FreeBSD__) @@ -32,19 +38,14 @@ #endif -#ifdef HAS_PDEATHSIG -# include -# include -#endif #ifdef WITH_SETPROCTITLE # include # include # if defined(__linux__) # include -# include # elif (defined(__FreeBSD__) || defined(__DragonFly__)) -# include -# include +//# include +//# include # elif (defined(__NetBSD__) || defined(__OpenBSD__)) // setproctitle() placed in stdlib.h # else # error setproctitle() not implemented, you can disable it using WITH_SETPROCTITLE=0 @@ -72,6 +73,7 @@ extern char **environ; #ifdef HAS_PDEATHSIG INLINE int process_track_parent_death(void) { + pid_t parent = getppid(); int signum = SIGTERM; # if defined(__linux__) int retval = prctl(PR_SET_PDEATHSIG, signum); @@ -85,8 +87,8 @@ INLINE int process_track_parent_death(void) { return -1; } - if (kill(getppid(), 0) < 0) { - LOG_PERROR("The parent process is already dead"); + if (kill(parent, 0) < 0) { + LOG_PERROR("The parent process %d is already dead", parent); return -1; } @@ -128,3 +130,11 @@ INLINE void process_set_name_prefix(int argc, char *argv[], const char *prefix) free(cmdline); } #endif + +INLINE void process_notify_parent(void) { + pid_t parent = getppid(); + + if (kill(parent, SIGUSR2) < 0) { + LOG_PERROR("Can't send SIGUSR2 to the parent process %d", parent); + } +}