1 /*****************************************************************************
2 #                                                                            #
3 #    uStreamer - Lightweight and fast MJPG-HTTP streamer.                    #
4 #                                                                            #
5 #    Copyright (C) 2018-2021  Maxim Devaev <mdevaev@gmail.com>               #
6 #                                                                            #
7 #    This program is free software: you can redistribute it and/or modify    #
8 #    it under the terms of the GNU General Public License as published by    #
9 #    the Free Software Foundation, either version 3 of the License, or       #
10 #    (at your option) any later version.                                     #
11 #                                                                            #
12 #    This program is distributed in the hope that it will be useful,         #
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of          #
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           #
15 #    GNU General Public License for more details.                            #
16 #                                                                            #
17 #    You should have received a copy of the GNU General Public License       #
18 #    along with this program.  If not, see <https://www.gnu.org/licenses/>.  #
19 #                                                                            #
20 *****************************************************************************/
21 
22 
23 #pragma once
24 
25 #include <stdbool.h>
26 #include <stdatomic.h>
27 
28 #include <sys/types.h>
29 
30 #include <pthread.h>
31 
32 #include "../libs/tools.h"
33 #include "../libs/threading.h"
34 #include "../libs/logging.h"
35 
36 
37 typedef struct worker_sx {
38 	pthread_t		tid;
39 	unsigned		number;
40 	char			*name;
41 
42 	long double		last_job_time;
43 
44 	pthread_mutex_t	has_job_mutex;
45 	void			*job;
46 	atomic_bool		has_job;
47 	bool			job_timely;
48 	bool			job_failed;
49 	long double		job_start_ts;
50 	pthread_cond_t	has_job_cond;
51 
52 	struct worker_sx *prev_wr;
53 	struct worker_sx *next_wr;
54 
55 	struct workers_pool_sx *pool;
56 } worker_s;
57 
58 typedef void *(*workers_pool_job_init_f)(void *arg);
59 typedef void (*workers_pool_job_destroy_f)(void *job);
60 typedef bool (*workers_pool_run_job_f)(worker_s *wr);
61 
62 typedef struct workers_pool_sx {
63 	const char		*name;
64 	long double		desired_interval;
65 
66 	workers_pool_job_destroy_f	job_destroy;
67 	workers_pool_run_job_f		run_job;
68 
69 	unsigned		n_workers;
70 	worker_s		*workers;
71 	worker_s		*oldest_wr;
72 	worker_s		*latest_wr;
73 
74 	long double		approx_job_time;
75 
76 	pthread_mutex_t	free_workers_mutex;
77 	unsigned		free_workers;
78 	pthread_cond_t	free_workers_cond;
79 
80 	atomic_bool		stop;
81 } workers_pool_s;
82 
83 
84 workers_pool_s *workers_pool_init(
85 	const char *name, const char *wr_prefix, unsigned n_workers, long double desired_interval,
86 	workers_pool_job_init_f job_init, void *job_init_arg,
87 	workers_pool_job_destroy_f job_destroy,
88 	workers_pool_run_job_f run_job);
89 
90 void workers_pool_destroy(workers_pool_s *pool);
91 
92 worker_s *workers_pool_wait(workers_pool_s *pool);
93 void workers_pool_assign(workers_pool_s *pool, worker_s *ready_wr/*, void *job*/);
94 
95 long double workers_pool_get_fluency_delay(workers_pool_s *pool, worker_s *ready_wr);
96