mirror of
https://github.com/pikvm/ustreamer.git
synced 2026-02-28 12:46:32 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ec02d46b9 | ||
|
|
527afb66df | ||
|
|
5502758a7e | ||
|
|
faa1776407 | ||
|
|
3d7fb8c8dd | ||
|
|
b5f814d71e | ||
|
|
6eafd4156a | ||
|
|
df1e4eaa06 | ||
|
|
d2bef81b03 | ||
|
|
7b3dffd072 | ||
|
|
1a6e9998fb | ||
|
|
9ab9561803 |
@@ -1,7 +1,7 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
current_version = 5.17
|
current_version = 5.20
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)
|
parse = (?P<major>\d+)\.(?P<minor>\d+)
|
||||||
serialize =
|
serialize =
|
||||||
{major}.{minor}
|
{major}.{minor}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
#define US_JLOG_ERROR(x_prefix, x_msg, ...) JANUS_LOG(LOG_ERR, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__)
|
#define US_JLOG_ERROR(x_prefix, x_msg, ...) JANUS_LOG(LOG_ERR, "== %s/%-9s -- " x_msg "\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define US_JLOG_PERROR(x_prefix, x_msg, ...) { \
|
#define US_JLOG_PERROR(x_prefix, x_msg, ...) { \
|
||||||
char m_perror_buf[1024] = {0}; \
|
char *const m_perror_str = us_errno_to_string(errno); \
|
||||||
char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \
|
JANUS_LOG(LOG_ERR, "[%s/%-9s] " x_msg ": %s\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__, m_perror_str); \
|
||||||
JANUS_LOG(LOG_ERR, "[%s/%-9s] " x_msg ": %s\n", US_PLUGIN_NAME, x_prefix, ##__VA_ARGS__, m_perror_ptr); \
|
free(m_perror_str); \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ us_queue_s *us_queue_init(unsigned capacity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void us_queue_destroy(us_queue_s *queue) {
|
void us_queue_destroy(us_queue_s *queue) {
|
||||||
|
US_COND_DESTROY(queue->empty_cond);
|
||||||
|
US_COND_DESTROY(queue->full_cond);
|
||||||
|
US_MUTEX_DESTROY(queue->mutex);
|
||||||
free(queue->items);
|
free(queue->items);
|
||||||
free(queue);
|
free(queue);
|
||||||
}
|
}
|
||||||
@@ -73,7 +76,7 @@ int us_queue_put(us_queue_s *queue, void *item, long double timeout) {
|
|||||||
++queue->in;
|
++queue->in;
|
||||||
queue->in %= queue->capacity;
|
queue->in %= queue->capacity;
|
||||||
US_MUTEX_UNLOCK(queue->mutex);
|
US_MUTEX_UNLOCK(queue->mutex);
|
||||||
assert(!pthread_cond_broadcast(&queue->empty_cond));
|
US_COND_BROADCAST(queue->empty_cond);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +88,7 @@ int us_queue_get(us_queue_s *queue, void **item, long double timeout) {
|
|||||||
++queue->out;
|
++queue->out;
|
||||||
queue->out %= queue->capacity;
|
queue->out %= queue->capacity;
|
||||||
US_MUTEX_UNLOCK(queue->mutex);
|
US_MUTEX_UNLOCK(queue->mutex);
|
||||||
assert(!pthread_cond_broadcast(&queue->full_cond));
|
US_COND_BROADCAST(queue->full_cond);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.\" Manpage for ustreamer-dump.
|
.\" Manpage for ustreamer-dump.
|
||||||
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
|
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
|
||||||
.TH USTREAMER-DUMP 1 "version 5.17" "January 2021"
|
.TH USTREAMER-DUMP 1 "version 5.20" "January 2021"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ustreamer-dump \- Dump uStreamer's memory sink to file
|
ustreamer-dump \- Dump uStreamer's memory sink to file
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.\" Manpage for ustreamer.
|
.\" Manpage for ustreamer.
|
||||||
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
|
.\" Open an issue or pull request to https://github.com/pikvm/ustreamer to correct errors or typos
|
||||||
.TH USTREAMER 1 "version 5.17" "November 2020"
|
.TH USTREAMER 1 "version 5.20" "November 2020"
|
||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ustreamer \- stream MJPEG video from any V4L2 device to the network
|
ustreamer \- stream MJPEG video from any V4L2 device to the network
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
pkgname=ustreamer
|
pkgname=ustreamer
|
||||||
pkgver=5.17
|
pkgver=5.20
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Lightweight and fast MJPEG-HTTP streamer"
|
pkgdesc="Lightweight and fast MJPEG-HTTP streamer"
|
||||||
url="https://github.com/pikvm/ustreamer"
|
url="https://github.com/pikvm/ustreamer"
|
||||||
@@ -22,8 +22,8 @@ if [ -e /usr/bin/python3 ]; then
|
|||||||
makedepends+=(python-setuptools)
|
makedepends+=(python-setuptools)
|
||||||
fi
|
fi
|
||||||
if [ -e /usr/include/janus/plugins/plugin.h ];then
|
if [ -e /usr/include/janus/plugins/plugin.h ];then
|
||||||
depends+=(janus-gateway-pikvm alsa-lib opus)
|
depends+=(janus-gateway alsa-lib opus)
|
||||||
makedepends+=(janus-gateway-pikvm alsa-lib opus)
|
makedepends+=(janus-gateway alsa-lib opus)
|
||||||
_options="$_options WITH_JANUS=1"
|
_options="$_options WITH_JANUS=1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=ustreamer
|
PKG_NAME:=ustreamer
|
||||||
PKG_VERSION:=5.17
|
PKG_VERSION:=5.20
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>
|
PKG_MAINTAINER:=Maxim Devaev <mdevaev@gmail.com>
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ def _find_sources(suffix: str) -> List[str]:
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup(
|
setup(
|
||||||
name="ustreamer",
|
name="ustreamer",
|
||||||
version="5.17",
|
version="5.20",
|
||||||
description="uStreamer tools",
|
description="uStreamer tools",
|
||||||
author="Maxim Devaev",
|
author="Maxim Devaev",
|
||||||
author_email="mdevaev@gmail.com",
|
author_email="mdevaev@gmail.com",
|
||||||
|
|||||||
@@ -151,12 +151,12 @@ int main(int argc, char *argv[]) {
|
|||||||
case _O_COUNT: OPT_NUMBER("--count", count, 0, LLONG_MAX, 0);
|
case _O_COUNT: OPT_NUMBER("--count", count, 0, LLONG_MAX, 0);
|
||||||
case _O_INTERVAL: OPT_LDOUBLE("--interval", interval, 0, 60);
|
case _O_INTERVAL: OPT_LDOUBLE("--interval", interval, 0, 60);
|
||||||
|
|
||||||
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0);
|
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_g_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0);
|
||||||
case _O_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF);
|
case _O_PERF: OPT_SET(us_g_log_level, US_LOG_LEVEL_PERF);
|
||||||
case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE);
|
case _O_VERBOSE: OPT_SET(us_g_log_level, US_LOG_LEVEL_VERBOSE);
|
||||||
case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG);
|
case _O_DEBUG: OPT_SET(us_g_log_level, US_LOG_LEVEL_DEBUG);
|
||||||
case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true);
|
case _O_FORCE_LOG_COLORS: OPT_SET(us_g_log_colored, true);
|
||||||
case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false);
|
case _O_NO_LOG_COLORS: OPT_SET(us_g_log_colored, false);
|
||||||
|
|
||||||
case _O_HELP: _help(stdout); return 0;
|
case _O_HELP: _help(stdout); return 0;
|
||||||
case _O_VERSION: puts(US_VERSION); return 0;
|
case _O_VERSION: puts(US_VERSION); return 0;
|
||||||
@@ -195,12 +195,9 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
|
|
||||||
static void _signal_handler(int signum) {
|
static void _signal_handler(int signum) {
|
||||||
switch (signum) {
|
char *const name = us_signum_to_string(signum);
|
||||||
case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break;
|
US_LOG_INFO_NOLOCK("===== Stopping by %s =====", name);
|
||||||
case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break;
|
free(name);
|
||||||
case SIGPIPE: US_LOG_INFO_NOLOCK("===== Stopping by SIGPIPE ====="); break;
|
|
||||||
default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break;
|
|
||||||
}
|
|
||||||
_g_stop = true;
|
_g_stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +327,7 @@ static void _help(FILE *fp) {
|
|||||||
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
|
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
|
||||||
SAY(" Enabling debugging messages can slow down the program.");
|
SAY(" Enabling debugging messages can slow down the program.");
|
||||||
SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
|
SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
|
||||||
SAY(" Default: %d.\n", us_log_level);
|
SAY(" Default: %d.\n", us_g_log_level);
|
||||||
SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
|
SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
|
||||||
SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
|
SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
|
||||||
SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");
|
SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define US_VERSION_MAJOR 5
|
#define US_VERSION_MAJOR 5
|
||||||
#define US_VERSION_MINOR 17
|
#define US_VERSION_MINOR 20
|
||||||
|
|
||||||
#define US_MAKE_VERSION2(_major, _minor) #_major "." #_minor
|
#define US_MAKE_VERSION2(_major, _minor) #_major "." #_minor
|
||||||
#define US_MAKE_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor)
|
#define US_MAKE_VERSION1(_major, _minor) US_MAKE_VERSION2(_major, _minor)
|
||||||
|
|||||||
@@ -23,8 +23,8 @@
|
|||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
|
|
||||||
enum us_log_level_t us_log_level;
|
enum us_log_level_t us_g_log_level;
|
||||||
|
|
||||||
bool us_log_colored;
|
bool us_g_log_colored;
|
||||||
|
|
||||||
pthread_mutex_t us_log_mutex;
|
pthread_mutex_t us_g_log_mutex;
|
||||||
|
|||||||
@@ -45,23 +45,23 @@ enum us_log_level_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern enum us_log_level_t us_log_level;
|
extern enum us_log_level_t us_g_log_level;
|
||||||
|
|
||||||
extern bool us_log_colored;
|
extern bool us_g_log_colored;
|
||||||
|
|
||||||
extern pthread_mutex_t us_log_mutex;
|
extern pthread_mutex_t us_g_log_mutex;
|
||||||
|
|
||||||
|
|
||||||
#define US_LOGGING_INIT { \
|
#define US_LOGGING_INIT { \
|
||||||
us_log_level = US_LOG_LEVEL_INFO; \
|
us_g_log_level = US_LOG_LEVEL_INFO; \
|
||||||
us_log_colored = isatty(2); \
|
us_g_log_colored = isatty(2); \
|
||||||
US_MUTEX_INIT(us_log_mutex); \
|
US_MUTEX_INIT(us_g_log_mutex); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOGGING_DESTROY US_MUTEX_DESTROY(us_log_mutex)
|
#define US_LOGGING_DESTROY US_MUTEX_DESTROY(us_g_log_mutex)
|
||||||
|
|
||||||
#define US_LOGGING_LOCK US_MUTEX_LOCK(us_log_mutex)
|
#define US_LOGGING_LOCK US_MUTEX_LOCK(us_g_log_mutex)
|
||||||
#define US_LOGGING_UNLOCK US_MUTEX_UNLOCK(us_log_mutex)
|
#define US_LOGGING_UNLOCK US_MUTEX_UNLOCK(us_g_log_mutex)
|
||||||
|
|
||||||
|
|
||||||
#define US_COLOR_GRAY "\x1b[30;1m"
|
#define US_COLOR_GRAY "\x1b[30;1m"
|
||||||
@@ -84,7 +84,7 @@ extern pthread_mutex_t us_log_mutex;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define US_SEP_DEBUG(x_ch) { \
|
#define US_SEP_DEBUG(x_ch) { \
|
||||||
if (us_log_level >= US_LOG_LEVEL_DEBUG) { \
|
if (us_g_log_level >= US_LOG_LEVEL_DEBUG) { \
|
||||||
US_SEP_INFO(x_ch); \
|
US_SEP_INFO(x_ch); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ extern pthread_mutex_t us_log_mutex;
|
|||||||
#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \
|
#define US_LOG_PRINTF_NOLOCK(x_label_color, x_label, x_msg_color, x_msg, ...) { \
|
||||||
char m_tname_buf[US_MAX_THREAD_NAME] = {0}; \
|
char m_tname_buf[US_MAX_THREAD_NAME] = {0}; \
|
||||||
us_thread_get_name(m_tname_buf); \
|
us_thread_get_name(m_tname_buf); \
|
||||||
if (us_log_colored) { \
|
if (us_g_log_colored) { \
|
||||||
fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \
|
fprintf(stderr, US_COLOR_GRAY "-- " x_label_color x_label US_COLOR_GRAY \
|
||||||
" [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \
|
" [%.03Lf %9s]" " -- " US_COLOR_RESET x_msg_color x_msg US_COLOR_RESET, \
|
||||||
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
|
us_get_now_monotonic(), m_tname_buf, ##__VA_ARGS__); \
|
||||||
@@ -116,9 +116,9 @@ extern pthread_mutex_t us_log_mutex;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_PERROR(x_msg, ...) { \
|
#define US_LOG_PERROR(x_msg, ...) { \
|
||||||
char m_perror_buf[1024] = {0}; \
|
char *const m_perror_str = us_errno_to_string(errno); \
|
||||||
char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1024); \
|
US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, m_perror_str); \
|
||||||
US_LOG_ERROR(x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \
|
free(m_perror_str); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_INFO(x_msg, ...) { \
|
#define US_LOG_INFO(x_msg, ...) { \
|
||||||
@@ -130,33 +130,33 @@ extern pthread_mutex_t us_log_mutex;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_PERF(x_msg, ...) { \
|
#define US_LOG_PERF(x_msg, ...) { \
|
||||||
if (us_log_level >= US_LOG_LEVEL_PERF) { \
|
if (us_g_log_level >= US_LOG_LEVEL_PERF) { \
|
||||||
US_LOG_PRINTF(US_COLOR_CYAN, "PERF ", US_COLOR_CYAN, x_msg, ##__VA_ARGS__); \
|
US_LOG_PRINTF(US_COLOR_CYAN, "PERF ", US_COLOR_CYAN, x_msg, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_PERF_FPS(x_msg, ...) { \
|
#define US_LOG_PERF_FPS(x_msg, ...) { \
|
||||||
if (us_log_level >= US_LOG_LEVEL_PERF) { \
|
if (us_g_log_level >= US_LOG_LEVEL_PERF) { \
|
||||||
US_LOG_PRINTF(US_COLOR_YELLOW, "PERF ", US_COLOR_YELLOW, x_msg, ##__VA_ARGS__); \
|
US_LOG_PRINTF(US_COLOR_YELLOW, "PERF ", US_COLOR_YELLOW, x_msg, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_VERBOSE(x_msg, ...) { \
|
#define US_LOG_VERBOSE(x_msg, ...) { \
|
||||||
if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \
|
if (us_g_log_level >= US_LOG_LEVEL_VERBOSE) { \
|
||||||
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg, ##__VA_ARGS__); \
|
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_VERBOSE_PERROR(x_msg, ...) { \
|
#define US_LOG_VERBOSE_PERROR(x_msg, ...) { \
|
||||||
if (us_log_level >= US_LOG_LEVEL_VERBOSE) { \
|
if (us_g_log_level >= US_LOG_LEVEL_VERBOSE) { \
|
||||||
char m_perror_buf[1024] = {0}; \
|
char *m_perror_str = us_errno_to_string(errno); \
|
||||||
char *m_perror_ptr = us_errno_to_string(errno, m_perror_buf, 1023); \
|
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg ": %s", ##__VA_ARGS__, m_perror_str); \
|
||||||
US_LOG_PRINTF(US_COLOR_BLUE, "VERB ", US_COLOR_BLUE, x_msg ": %s", ##__VA_ARGS__, m_perror_ptr); \
|
free(m_perror_str); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define US_LOG_DEBUG(x_msg, ...) { \
|
#define US_LOG_DEBUG(x_msg, ...) { \
|
||||||
if (us_log_level >= US_LOG_LEVEL_DEBUG) { \
|
if (us_g_log_level >= US_LOG_LEVEL_DEBUG) { \
|
||||||
US_LOG_PRINTF(US_COLOR_GRAY, "DEBUG", US_COLOR_GRAY, x_msg, ##__VA_ARGS__); \
|
US_LOG_PRINTF(US_COLOR_GRAY, "DEBUG", US_COLOR_GRAY, x_msg, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@
|
|||||||
#define US_COND_INIT(x_cond) assert(!pthread_cond_init(&(x_cond), NULL))
|
#define US_COND_INIT(x_cond) assert(!pthread_cond_init(&(x_cond), NULL))
|
||||||
#define US_COND_DESTROY(x_cond) assert(!pthread_cond_destroy(&(x_cond)))
|
#define US_COND_DESTROY(x_cond) assert(!pthread_cond_destroy(&(x_cond)))
|
||||||
#define US_COND_SIGNAL(x_cond) assert(!pthread_cond_signal(&(x_cond)))
|
#define US_COND_SIGNAL(x_cond) assert(!pthread_cond_signal(&(x_cond)))
|
||||||
#define US_COND_WAIT_TRUE(x_var, x_cond, x_mutex) { while(!(x_var)) assert(!pthread_cond_wait(&(x_cond), &(x_mutex))); }
|
#define US_COND_BROADCAST(x_cond) assert(!pthread_cond_broadcast(&(x_cond)))
|
||||||
|
#define US_COND_WAIT_FOR(x_var, x_cond, x_mutex) { while(!(x_var)) assert(!pthread_cond_wait(&(x_cond), &(x_mutex))); }
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_PTHREAD_NP
|
#ifdef WITH_PTHREAD_NP
|
||||||
|
|||||||
@@ -38,6 +38,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 32
|
||||||
|
# define HAS_SIGABBREV_NP
|
||||||
|
#else
|
||||||
|
# include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
# error WTF dude? Asserts are good things!
|
# error WTF dude? Asserts are good things!
|
||||||
@@ -181,15 +187,34 @@ INLINE int us_flock_timedwait_monotonic(int fd, long double timeout) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE char *us_errno_to_string(int error, char *buf, size_t size) {
|
INLINE char *us_errno_to_string(int error) {
|
||||||
assert(buf != NULL);
|
|
||||||
assert(size > 0);
|
|
||||||
locale_t locale = newlocale(LC_MESSAGES_MASK, "C", NULL);
|
locale_t locale = newlocale(LC_MESSAGES_MASK, "C", NULL);
|
||||||
const char *str = "!!! newlocale() error !!!";
|
char *buf;
|
||||||
strncpy(buf, (locale ? strerror_l(error, locale) : str), size - 1);
|
|
||||||
buf[size - 1] = '\0';
|
|
||||||
if (locale) {
|
if (locale) {
|
||||||
|
buf = us_strdup(strerror_l(error, locale));
|
||||||
freelocale(locale);
|
freelocale(locale);
|
||||||
|
} else {
|
||||||
|
buf = us_strdup("!!! newlocale() error !!!");
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE char *us_signum_to_string(int signum) {
|
||||||
|
# ifdef HAS_SIGABBREV_NP
|
||||||
|
const char *const name = sigabbrev_np(signum);
|
||||||
|
# else
|
||||||
|
const char *const name = (
|
||||||
|
signum == SIGTERM ? "TERM" :
|
||||||
|
signum == SIGINT ? "INT" :
|
||||||
|
signum == SIGPIPE ? "PIPE" :
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
# endif
|
||||||
|
char *buf;
|
||||||
|
if (name != NULL) {
|
||||||
|
US_ASPRINTF(buf, "SIG%s", name);
|
||||||
|
} else {
|
||||||
|
US_ASPRINTF(buf, "SIG[%d]", signum);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
|
|
||||||
us_gpio_s us_gpio = {
|
us_gpio_s us_g_gpio = {
|
||||||
.path = "/dev/gpiochip0",
|
.path = "/dev/gpiochip0",
|
||||||
.consumer_prefix = "ustreamer",
|
.consumer_prefix = "ustreamer",
|
||||||
|
|
||||||
@@ -51,42 +51,42 @@ static void _gpio_output_destroy(us_gpio_output_s *output);
|
|||||||
|
|
||||||
|
|
||||||
void us_gpio_init(void) {
|
void us_gpio_init(void) {
|
||||||
assert(us_gpio.chip == NULL);
|
assert(us_g_gpio.chip == NULL);
|
||||||
if (
|
if (
|
||||||
us_gpio.prog_running.pin >= 0
|
us_g_gpio.prog_running.pin >= 0
|
||||||
|| us_gpio.stream_online.pin >= 0
|
|| us_g_gpio.stream_online.pin >= 0
|
||||||
|| us_gpio.has_http_clients.pin >= 0
|
|| us_g_gpio.has_http_clients.pin >= 0
|
||||||
) {
|
) {
|
||||||
US_MUTEX_INIT(us_gpio.mutex);
|
US_MUTEX_INIT(us_g_gpio.mutex);
|
||||||
US_LOG_INFO("GPIO: Using chip device: %s", us_gpio.path);
|
US_LOG_INFO("GPIO: Using chip device: %s", us_g_gpio.path);
|
||||||
if ((us_gpio.chip = gpiod_chip_open(us_gpio.path)) != NULL) {
|
if ((us_g_gpio.chip = gpiod_chip_open(us_g_gpio.path)) != NULL) {
|
||||||
_gpio_output_init(&us_gpio.prog_running);
|
_gpio_output_init(&us_g_gpio.prog_running);
|
||||||
_gpio_output_init(&us_gpio.stream_online);
|
_gpio_output_init(&us_g_gpio.stream_online);
|
||||||
_gpio_output_init(&us_gpio.has_http_clients);
|
_gpio_output_init(&us_g_gpio.has_http_clients);
|
||||||
} else {
|
} else {
|
||||||
US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_gpio.path);
|
US_LOG_PERROR("GPIO: Can't initialize chip device %s", us_g_gpio.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void us_gpio_destroy(void) {
|
void us_gpio_destroy(void) {
|
||||||
_gpio_output_destroy(&us_gpio.prog_running);
|
_gpio_output_destroy(&us_g_gpio.prog_running);
|
||||||
_gpio_output_destroy(&us_gpio.stream_online);
|
_gpio_output_destroy(&us_g_gpio.stream_online);
|
||||||
_gpio_output_destroy(&us_gpio.has_http_clients);
|
_gpio_output_destroy(&us_g_gpio.has_http_clients);
|
||||||
if (us_gpio.chip != NULL) {
|
if (us_g_gpio.chip != NULL) {
|
||||||
gpiod_chip_close(us_gpio.chip);
|
gpiod_chip_close(us_g_gpio.chip);
|
||||||
us_gpio.chip = NULL;
|
us_g_gpio.chip = NULL;
|
||||||
US_MUTEX_DESTROY(us_gpio.mutex);
|
US_MUTEX_DESTROY(us_g_gpio.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
assert(us_gpio.chip != NULL);
|
assert(us_g_gpio.chip != NULL);
|
||||||
assert(output->line != NULL);
|
assert(output->line != NULL);
|
||||||
assert(output->state != state); // Must be checked in macro for the performance
|
assert(output->state != state); // Must be checked in macro for the performance
|
||||||
US_MUTEX_LOCK(us_gpio.mutex);
|
US_MUTEX_LOCK(us_g_gpio.mutex);
|
||||||
|
|
||||||
if (gpiod_line_set_value(output->line, (int)state) < 0) { \
|
if (gpiod_line_set_value(output->line, (int)state) < 0) { \
|
||||||
US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \
|
US_LOG_PERROR("GPIO: Can't write value %d to line %s (will be disabled)", state, output->consumer); \
|
||||||
@@ -94,18 +94,18 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state) {
|
|||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
US_MUTEX_UNLOCK(us_gpio.mutex);
|
US_MUTEX_UNLOCK(us_g_gpio.mutex);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _gpio_output_init(us_gpio_output_s *output) {
|
static void _gpio_output_init(us_gpio_output_s *output) {
|
||||||
assert(us_gpio.chip != NULL);
|
assert(us_g_gpio.chip != NULL);
|
||||||
assert(output->line == NULL);
|
assert(output->line == NULL);
|
||||||
|
|
||||||
US_ASPRINTF(output->consumer, "%s::%s", us_gpio.consumer_prefix, output->role);
|
US_ASPRINTF(output->consumer, "%s::%s", us_g_gpio.consumer_prefix, output->role);
|
||||||
|
|
||||||
if (output->pin >= 0) {
|
if (output->pin >= 0) {
|
||||||
if ((output->line = gpiod_chip_get_line(us_gpio.chip, output->pin)) != NULL) {
|
if ((output->line = gpiod_chip_get_line(us_g_gpio.chip, output->pin)) != NULL) {
|
||||||
if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) {
|
if (gpiod_line_request_output(output->line, output->consumer, 0) < 0) {
|
||||||
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
|
US_LOG_PERROR("GPIO: Can't request pin=%d as %s", output->pin, output->consumer);
|
||||||
_gpio_output_destroy(output);
|
_gpio_output_destroy(output);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ typedef struct {
|
|||||||
} us_gpio_s;
|
} us_gpio_s;
|
||||||
|
|
||||||
|
|
||||||
extern us_gpio_s us_gpio;
|
extern us_gpio_s us_g_gpio;
|
||||||
|
|
||||||
|
|
||||||
void us_gpio_init(void);
|
void us_gpio_init(void);
|
||||||
@@ -73,15 +73,15 @@ int us_gpio_inner_set(us_gpio_output_s *output, bool state);
|
|||||||
}
|
}
|
||||||
|
|
||||||
INLINE void us_gpio_set_prog_running(bool state) {
|
INLINE void us_gpio_set_prog_running(bool state) {
|
||||||
SET_STATE(us_gpio.prog_running, state);
|
SET_STATE(us_g_gpio.prog_running, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void us_gpio_set_stream_online(bool state) {
|
INLINE void us_gpio_set_stream_online(bool state) {
|
||||||
SET_STATE(us_gpio.stream_online, state);
|
SET_STATE(us_g_gpio.stream_online, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE void us_gpio_set_has_http_clients(bool state) {
|
INLINE void us_gpio_set_has_http_clients(bool state) {
|
||||||
SET_STATE(us_gpio.has_http_clients, state);
|
SET_STATE(us_g_gpio.has_http_clients, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SET_STATE
|
#undef SET_STATE
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ char *us_bufferevent_format_reason(short what) {
|
|||||||
US_CALLOC(reason, 2048);
|
US_CALLOC(reason, 2048);
|
||||||
|
|
||||||
// evutil_socket_error_to_string() is not thread-safe
|
// evutil_socket_error_to_string() is not thread-safe
|
||||||
char perror_buf[1024] = {0};
|
char *const perror_str = us_errno_to_string(EVUTIL_SOCKET_ERROR());
|
||||||
const char *perror_ptr = us_errno_to_string(EVUTIL_SOCKET_ERROR(), perror_buf, 1024);
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
strcat(reason, perror_ptr);
|
strcat(reason, perror_str);
|
||||||
|
free(perror_str);
|
||||||
strcat(reason, " (");
|
strcat(reason, " (");
|
||||||
|
|
||||||
# define FILL_REASON(x_bev, x_name) { \
|
# define FILL_REASON(x_bev, x_name) { \
|
||||||
|
|||||||
@@ -40,12 +40,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
static us_stream_s *_g_stream = NULL;
|
||||||
us_stream_s *stream;
|
static us_server_s *_g_server = NULL;
|
||||||
us_server_s *server;
|
|
||||||
} _main_context_s;
|
|
||||||
|
|
||||||
static _main_context_s *_ctx;
|
|
||||||
|
|
||||||
static void _block_thread_signals(void) {
|
static void _block_thread_signals(void) {
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
@@ -58,25 +55,23 @@ static void _block_thread_signals(void) {
|
|||||||
static void *_stream_loop_thread(UNUSED void *arg) {
|
static void *_stream_loop_thread(UNUSED void *arg) {
|
||||||
US_THREAD_RENAME("stream");
|
US_THREAD_RENAME("stream");
|
||||||
_block_thread_signals();
|
_block_thread_signals();
|
||||||
us_stream_loop(_ctx->stream);
|
us_stream_loop(_g_stream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_server_loop_thread(UNUSED void *arg) {
|
static void *_server_loop_thread(UNUSED void *arg) {
|
||||||
US_THREAD_RENAME("http");
|
US_THREAD_RENAME("http");
|
||||||
_block_thread_signals();
|
_block_thread_signals();
|
||||||
us_server_loop(_ctx->server);
|
us_server_loop(_g_server);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _signal_handler(int signum) {
|
static void _signal_handler(int signum) {
|
||||||
switch (signum) {
|
char *const name = us_signum_to_string(signum);
|
||||||
case SIGTERM: US_LOG_INFO_NOLOCK("===== Stopping by SIGTERM ====="); break;
|
US_LOG_INFO_NOLOCK("===== Stopping by %s =====", name);
|
||||||
case SIGINT: US_LOG_INFO_NOLOCK("===== Stopping by SIGINT ====="); break;
|
free(name);
|
||||||
default: US_LOG_INFO_NOLOCK("===== Stopping by %d =====", signum); break;
|
us_stream_loop_break(_g_stream);
|
||||||
}
|
us_server_loop_break(_g_server);
|
||||||
us_stream_loop_break(_ctx->stream);
|
|
||||||
us_server_loop_break(_ctx->server);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _install_signal_handlers(void) {
|
static void _install_signal_handlers(void) {
|
||||||
@@ -107,22 +102,17 @@ int main(int argc, char *argv[]) {
|
|||||||
us_options_s *options = us_options_init(argc, argv);
|
us_options_s *options = us_options_init(argc, argv);
|
||||||
us_device_s *dev = us_device_init();
|
us_device_s *dev = us_device_init();
|
||||||
us_encoder_s *enc = us_encoder_init();
|
us_encoder_s *enc = us_encoder_init();
|
||||||
us_stream_s *stream = us_stream_init(dev, enc);
|
_g_stream = us_stream_init(dev, enc);
|
||||||
us_server_s *server = us_server_init(stream);
|
_g_server = us_server_init(_g_stream);
|
||||||
|
|
||||||
if ((exit_code = options_parse(options, dev, enc, stream, server)) == 0) {
|
if ((exit_code = options_parse(options, dev, enc, _g_stream, _g_server)) == 0) {
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
us_gpio_init();
|
us_gpio_init();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
_install_signal_handlers();
|
_install_signal_handlers();
|
||||||
|
|
||||||
_main_context_s ctx;
|
if ((exit_code = us_server_listen(_g_server)) == 0) {
|
||||||
ctx.stream = stream;
|
|
||||||
ctx.server = server;
|
|
||||||
_ctx = &ctx;
|
|
||||||
|
|
||||||
if ((exit_code = us_server_listen(server)) == 0) {
|
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
us_gpio_set_prog_running(true);
|
us_gpio_set_prog_running(true);
|
||||||
# endif
|
# endif
|
||||||
@@ -141,8 +131,8 @@ int main(int argc, char *argv[]) {
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
us_server_destroy(server);
|
us_server_destroy(_g_server);
|
||||||
us_stream_destroy(stream);
|
us_stream_destroy(_g_stream);
|
||||||
us_encoder_destroy(enc);
|
us_encoder_destroy(enc);
|
||||||
us_device_destroy(dev);
|
us_device_destroy(dev);
|
||||||
us_options_destroy(options);
|
us_options_destroy(options);
|
||||||
|
|||||||
@@ -437,11 +437,11 @@ int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us
|
|||||||
# undef ADD_SINK
|
# undef ADD_SINK
|
||||||
|
|
||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
case _O_GPIO_DEVICE: OPT_SET(us_gpio.path, optarg);
|
case _O_GPIO_DEVICE: OPT_SET(us_g_gpio.path, optarg);
|
||||||
case _O_GPIO_CONSUMER_PREFIX: OPT_SET(us_gpio.consumer_prefix, optarg);
|
case _O_GPIO_CONSUMER_PREFIX: OPT_SET(us_g_gpio.consumer_prefix, optarg);
|
||||||
case _O_GPIO_PROG_RUNNING: OPT_NUMBER("--gpio-prog-running", us_gpio.prog_running.pin, 0, 256, 0);
|
case _O_GPIO_PROG_RUNNING: OPT_NUMBER("--gpio-prog-running", us_g_gpio.prog_running.pin, 0, 256, 0);
|
||||||
case _O_GPIO_STREAM_ONLINE: OPT_NUMBER("--gpio-stream-online", us_gpio.stream_online.pin, 0, 256, 0);
|
case _O_GPIO_STREAM_ONLINE: OPT_NUMBER("--gpio-stream-online", us_g_gpio.stream_online.pin, 0, 256, 0);
|
||||||
case _O_GPIO_HAS_HTTP_CLIENTS: OPT_NUMBER("--gpio-has-http-clients", us_gpio.has_http_clients.pin, 0, 256, 0);
|
case _O_GPIO_HAS_HTTP_CLIENTS: OPT_NUMBER("--gpio-has-http-clients", us_g_gpio.has_http_clients.pin, 0, 256, 0);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef HAS_PDEATHSIG
|
# ifdef HAS_PDEATHSIG
|
||||||
@@ -457,12 +457,12 @@ int options_parse(us_options_s *options, us_device_s *dev, us_encoder_s *enc, us
|
|||||||
# endif
|
# endif
|
||||||
case _O_NOTIFY_PARENT: OPT_SET(server->notify_parent, true);
|
case _O_NOTIFY_PARENT: OPT_SET(server->notify_parent, true);
|
||||||
|
|
||||||
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0);
|
case _O_LOG_LEVEL: OPT_NUMBER("--log-level", us_g_log_level, US_LOG_LEVEL_INFO, US_LOG_LEVEL_DEBUG, 0);
|
||||||
case _O_PERF: OPT_SET(us_log_level, US_LOG_LEVEL_PERF);
|
case _O_PERF: OPT_SET(us_g_log_level, US_LOG_LEVEL_PERF);
|
||||||
case _O_VERBOSE: OPT_SET(us_log_level, US_LOG_LEVEL_VERBOSE);
|
case _O_VERBOSE: OPT_SET(us_g_log_level, US_LOG_LEVEL_VERBOSE);
|
||||||
case _O_DEBUG: OPT_SET(us_log_level, US_LOG_LEVEL_DEBUG);
|
case _O_DEBUG: OPT_SET(us_g_log_level, US_LOG_LEVEL_DEBUG);
|
||||||
case _O_FORCE_LOG_COLORS: OPT_SET(us_log_colored, true);
|
case _O_FORCE_LOG_COLORS: OPT_SET(us_g_log_colored, true);
|
||||||
case _O_NO_LOG_COLORS: OPT_SET(us_log_colored, false);
|
case _O_NO_LOG_COLORS: OPT_SET(us_g_log_colored, false);
|
||||||
|
|
||||||
case _O_HELP: _help(stdout, dev, enc, stream, server); return 1;
|
case _O_HELP: _help(stdout, dev, enc, stream, server); return 1;
|
||||||
case _O_VERSION: puts(US_VERSION); return 1;
|
case _O_VERSION: puts(US_VERSION); return 1;
|
||||||
@@ -676,8 +676,8 @@ static void _help(FILE *fp, us_device_s *dev, us_encoder_s *enc, us_stream_s *st
|
|||||||
# ifdef WITH_GPIO
|
# ifdef WITH_GPIO
|
||||||
SAY("GPIO options:");
|
SAY("GPIO options:");
|
||||||
SAY("═════════════");
|
SAY("═════════════");
|
||||||
SAY(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n", us_gpio.path);
|
SAY(" --gpio-device </dev/path> ───── Path to GPIO character device. Default: %s.\n", us_g_gpio.path);
|
||||||
SAY(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n", us_gpio.consumer_prefix);
|
SAY(" --gpio-consumer-prefix <str> ── Consumer prefix for GPIO outputs. Default: %s.\n", us_g_gpio.consumer_prefix);
|
||||||
SAY(" --gpio-prog-running <pin> ───── Set 1 on GPIO pin while uStreamer is running. Default: disabled.\n");
|
SAY(" --gpio-prog-running <pin> ───── Set 1 on GPIO pin while uStreamer is running. Default: disabled.\n");
|
||||||
SAY(" --gpio-stream-online <pin> ──── Set 1 while streaming. Default: disabled.\n");
|
SAY(" --gpio-stream-online <pin> ──── Set 1 while streaming. Default: disabled.\n");
|
||||||
SAY(" --gpio-has-http-clients <pin> ─ Set 1 while stream has at least one client. Default: disabled.\n");
|
SAY(" --gpio-has-http-clients <pin> ─ Set 1 while stream has at least one client. Default: disabled.\n");
|
||||||
@@ -702,7 +702,7 @@ static void _help(FILE *fp, us_device_s *dev, us_encoder_s *enc, us_stream_s *st
|
|||||||
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
|
SAY(" --log-level <N> ──── Verbosity level of messages from 0 (info) to 3 (debug).");
|
||||||
SAY(" Enabling debugging messages can slow down the program.");
|
SAY(" Enabling debugging messages can slow down the program.");
|
||||||
SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
|
SAY(" Available levels: 0 (info), 1 (performance), 2 (verbose), 3 (debug).");
|
||||||
SAY(" Default: %d.\n", us_log_level);
|
SAY(" Default: %d.\n", us_g_log_level);
|
||||||
SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
|
SAY(" --perf ───────────── Enable performance messages (same as --log-level=1). Default: disabled.\n");
|
||||||
SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
|
SAY(" --verbose ────────── Enable verbose messages and lower (same as --log-level=2). Default: disabled.\n");
|
||||||
SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");
|
SAY(" --debug ──────────── Enable debug messages and lower (same as --log-level=3). Default: disabled.\n");
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ us_worker_s *us_workers_pool_wait(us_workers_pool_s *pool) {
|
|||||||
us_worker_s *ready_wr = NULL;
|
us_worker_s *ready_wr = NULL;
|
||||||
|
|
||||||
US_MUTEX_LOCK(pool->free_workers_mutex);
|
US_MUTEX_LOCK(pool->free_workers_mutex);
|
||||||
US_COND_WAIT_TRUE(pool->free_workers, pool->free_workers_cond, pool->free_workers_mutex);
|
US_COND_WAIT_FOR(pool->free_workers, pool->free_workers_cond, pool->free_workers_mutex);
|
||||||
US_MUTEX_UNLOCK(pool->free_workers_mutex);
|
US_MUTEX_UNLOCK(pool->free_workers_mutex);
|
||||||
|
|
||||||
if (pool->oldest_wr && !atomic_load(&pool->oldest_wr->has_job)) {
|
if (pool->oldest_wr && !atomic_load(&pool->oldest_wr->has_job)) {
|
||||||
@@ -185,7 +185,7 @@ static void *_worker_thread(void *v_worker) {
|
|||||||
US_LOG_DEBUG("Worker %s waiting for a new job ...", wr->name);
|
US_LOG_DEBUG("Worker %s waiting for a new job ...", wr->name);
|
||||||
|
|
||||||
US_MUTEX_LOCK(wr->has_job_mutex);
|
US_MUTEX_LOCK(wr->has_job_mutex);
|
||||||
US_COND_WAIT_TRUE(atomic_load(&wr->has_job), wr->has_job_cond, wr->has_job_mutex);
|
US_COND_WAIT_FOR(atomic_load(&wr->has_job), wr->has_job_cond, wr->has_job_mutex);
|
||||||
US_MUTEX_UNLOCK(wr->has_job_mutex);
|
US_MUTEX_UNLOCK(wr->has_job_mutex);
|
||||||
|
|
||||||
if (!atomic_load(&wr->pool->stop)) {
|
if (!atomic_load(&wr->pool->stop)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user