wyebadblock/wyebrun.c

656 lines
13 KiB
C
Raw Normal View History

2018-05-19 15:51:50 +00:00
/*
Copyright 2018 jun7@hush.mail
This file is part of wyebrun.
wyebrun is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
wyebrun is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with wyebrun. If not, see <http://www.gnu.org/licenses/>.
*/
2018-06-08 14:29:53 +00:00
//getpid
#include <sys/types.h>
#include <unistd.h>
2018-05-19 15:51:50 +00:00
//flock
#include <sys/file.h>
//monitor
#include <gio/gio.h>
2018-05-19 15:51:50 +00:00
#include "wyebrun.h"
#define ROOTNAME "wyebrun"
2018-06-05 09:34:05 +00:00
#define CLIDIR "clients"
2018-05-19 15:51:50 +00:00
#define PREFIX WYEBPREFIX
2018-06-05 09:34:05 +00:00
#define KEEPS WYEBKEEPSEC
2018-05-19 15:51:50 +00:00
#define INPUT "wyebinput"
#define PING "wyebping"
#define DPINGTIME 1000
#define P(f, ...) g_print(#f"\n", __VA_ARGS__);
#if DEBUG
2018-05-20 04:17:11 +00:00
# define D(f, ...) g_print("#"#f"\n", __VA_ARGS__);
# define DD(a) g_print("#"#a"\n");
2018-05-19 15:51:50 +00:00
#else
# define D(...) ;
# define DD(a) ;
#endif
typedef enum {
//to svr
CSuntil = 'u',
CSdata = 'd',
CSping = 'p',
//to client
CCwoke = 'w',
CCret = 'r', //retrun data
CClost = 'l', //we lost the req
} Com;
//shared
static void fatal(int i)
{
P(\n!!! fatal %d !!!\n, i)
exit(1);
}
static void mkdirif(char *path)
{
char *dir = g_path_get_dirname(path);
if (!g_file_test(dir, G_FILE_TEST_EXISTS))
g_mkdir_with_parents(dir, 0700);
g_free(dir);
}
static char *ipcpath(char *exe, char *name)
{
return g_build_filename(g_get_user_runtime_dir(),
2018-06-23 06:42:45 +00:00
ROOTNAME, exe, name, NULL);
2018-05-19 15:51:50 +00:00
}
static bool ipcsend(char *exe, char *name,
Com type, char *caller, char *data)
{
2018-06-23 06:42:45 +00:00
char *path = ipcpath(exe, name);
2018-05-19 15:51:50 +00:00
char *esc = g_strescape(data ?: "", "");
D(ipcsend exe:%s name:%s type:%c sizs:%lu, exe, name, type, strlen(esc ?: ""))
2018-05-19 15:51:50 +00:00
char *line = g_strdup_printf("%c%s:%s\n", type, caller ?: "", esc);
int len = strlen(line);
2018-05-19 15:51:50 +00:00
g_free(esc);
bool ret = false;
int pp = open(path, O_WRONLY | O_NONBLOCK);
if (pp > -1)
{
if (len > PIPE_BUF) //4096 => len is atomic
{
flock(pp, LOCK_EX);
fcntl(pp, F_SETFL, 0); //clear O_NONBLOCK to write len > 65536;
}
2018-06-16 07:52:54 +00:00
else
flock(pp, LOCK_SH);
ret = write(pp, line, len) == len;
close(pp);
}
2018-06-23 05:31:24 +00:00
2018-05-19 15:51:50 +00:00
g_free(line);
g_free(path);
2018-06-04 20:54:27 +00:00
2018-06-23 05:31:24 +00:00
//D(ipcsend ret %d, ret)
2018-05-19 15:51:50 +00:00
return ret;
}
static gboolean ipccb(GIOChannel *ch, GIOCondition cnd, gpointer p);
2018-05-19 15:51:50 +00:00
2018-06-05 09:34:05 +00:00
static GSource *ipcwatch(char *exe, char *name, GMainContext *ctx, gpointer p)
{
2018-06-23 06:42:45 +00:00
char *path = ipcpath(exe, name);
if (!g_file_test(path, G_FILE_TEST_EXISTS))
{
mkdirif(path);
mkfifo(path, 0600);
}
2018-05-19 15:51:50 +00:00
GIOChannel *io = g_io_channel_new_file(path, "r+", NULL);
GSource *watch = g_io_create_watch(io, G_IO_IN);
g_io_channel_unref(io);
2018-06-05 09:34:05 +00:00
g_source_set_callback(watch, (GSourceFunc)ipccb, p, NULL);
2018-05-19 15:51:50 +00:00
g_source_attach(watch, ctx);
g_free(path);
return watch;
}
//@server
2019-09-28 13:54:36 +00:00
static char *svrexe;
static GMainLoop *sloop;
static wyebdataf dataf;
static GHashTable *orders;
2018-06-04 20:54:27 +00:00
static GMutex ordersm;
2018-06-04 20:54:27 +00:00
static gboolean quitif(gpointer p)
2018-05-19 15:51:50 +00:00
{
2018-06-04 20:54:27 +00:00
g_mutex_lock(&ordersm);
if (!g_hash_table_size(orders))
{
DD(SVR QUITS\n)
g_main_loop_quit(sloop);
}
g_mutex_unlock(&ordersm);
return true;
2018-05-19 15:51:50 +00:00
}
static void until(int sec)
{
if (!sloop) return;
2019-09-28 13:54:36 +00:00
static guint last;
2018-06-05 09:34:05 +00:00
static GMutex m;
g_mutex_lock(&m);
2018-05-19 15:51:50 +00:00
if (last)
g_source_remove(last);
2018-06-04 20:54:27 +00:00
last = g_timeout_add_full(G_PRIORITY_LOW * 2, sec * 1000, quitif, NULL, NULL);
2018-06-05 09:34:05 +00:00
g_mutex_unlock(&m);
2018-05-19 15:51:50 +00:00
}
static gpointer pingt(gpointer p)
{
GMainContext *ctx = g_main_context_new();
2018-06-05 09:34:05 +00:00
ipcwatch(svrexe, PING, ctx, NULL);
2018-05-19 15:51:50 +00:00
g_main_loop_run(g_main_loop_new(ctx, true));
return NULL;
}
void wyebwatch(char *exe, char *caller, wyebdataf func)
{
svrexe = exe;
dataf = func;
2018-06-04 03:32:27 +00:00
orders = g_hash_table_new(g_str_hash, g_str_equal);
2018-06-05 09:34:05 +00:00
until(KEEPS);
2018-05-19 15:51:50 +00:00
2018-06-05 09:34:05 +00:00
g_thread_unref(g_thread_new("ping", pingt, NULL));
ipcwatch(exe, INPUT, g_main_context_default(), NULL);
2018-05-19 15:51:50 +00:00
2018-06-05 09:34:05 +00:00
if (!ipcsend(CLIDIR, caller, CCwoke, "", NULL))
2018-05-19 15:51:50 +00:00
fatal(1);
}
2018-06-04 03:32:27 +00:00
static void monitorcb(GFileMonitor *m, GFile *f, GFile *o, GFileMonitorEvent e,
gpointer p)
{
if (e == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
g_timeout_add(100, quitif, NULL);
}
2018-05-19 15:51:50 +00:00
static gboolean svrinit(char *caller)
{
wyebwatch(svrexe, caller, dataf);
char path[PATH_MAX];
2018-06-08 16:18:49 +00:00
(void)readlink("/proc/self/exe", path, PATH_MAX);
D(exepath %s, path)
GFile *gf = g_file_new_for_path(path);
GFileMonitor *gm = g_file_monitor_file(
gf, G_FILE_MONITOR_NONE, NULL, NULL);
g_signal_connect(gm, "changed", G_CALLBACK(monitorcb), NULL);
g_object_unref(gf);
2018-05-19 15:51:50 +00:00
return false;
}
bool wyebsvr(int argc, char **argv, wyebdataf func)
{
2018-06-08 13:37:36 +00:00
if (argc < 3 || strcmp(argv[1], PREFIX)) return false;
2018-05-19 15:51:50 +00:00
svrexe = argv[0];
dataf = func;
sloop = g_main_loop_new(NULL, false);
2018-06-08 13:37:36 +00:00
g_idle_add((GSourceFunc)svrinit, argv[2]);
2018-05-19 15:51:50 +00:00
g_main_loop_run(sloop);
return true;
}
2018-06-04 20:54:27 +00:00
typedef struct {
char *caller;
2018-06-05 09:34:05 +00:00
char *data;
2018-06-04 20:54:27 +00:00
} Dataargs;
2018-06-05 09:34:05 +00:00
static void getdata(gpointer p, gpointer ap)
2018-05-19 15:51:50 +00:00
{
2018-06-04 20:54:27 +00:00
Dataargs *args = p;
2018-05-19 15:51:50 +00:00
2018-06-08 16:18:49 +00:00
if (*args->caller)
{
g_mutex_lock(&ordersm);
g_hash_table_add(orders, args->caller);
g_mutex_unlock(&ordersm);
}
2018-06-04 20:54:27 +00:00
2018-06-05 09:34:05 +00:00
char *data = dataf(args->data);
if (*args->caller && !ipcsend(CLIDIR, args->caller, CCret, "", data)) fatal(2);
2018-05-19 15:51:50 +00:00
g_free(data);
2018-06-04 20:54:27 +00:00
2018-06-08 16:18:49 +00:00
if (*args->caller)
{
g_mutex_lock(&ordersm);
g_hash_table_remove(orders, args->caller);
g_mutex_unlock(&ordersm);
}
2018-06-04 20:54:27 +00:00
g_free(args->caller);
2018-06-05 09:34:05 +00:00
g_free(args->data);
2018-06-04 20:54:27 +00:00
g_free(args);
2018-05-19 15:51:50 +00:00
}
//@client
2018-06-05 09:34:05 +00:00
typedef struct {
GMutex retm;
GMainContext *wctx;
GMainLoop *loop;
2018-06-06 04:18:17 +00:00
GSource *watch;
2018-06-05 09:34:05 +00:00
char *pid;
char *retdata;
char *pppath;
char *exe; //do not free. this is tmp
} Client;
2018-06-06 04:18:17 +00:00
2019-09-28 13:54:36 +00:00
static GSList *rmpath;
2018-06-06 15:59:42 +00:00
static GMutex rmm;
2018-06-06 04:18:17 +00:00
static void __attribute__((destructor)) removepp()
{
for (; rmpath; rmpath = rmpath->next)
remove(rmpath->data);
}
static Client *makecl()
2018-06-05 09:34:05 +00:00
{
Client *c = g_new0(Client, 1);
2018-12-16 11:32:18 +00:00
// g_mutex_init(&c->retm);
2019-09-28 13:54:36 +00:00
static int tid;
c->pid = g_strdup_printf("%d-%u", tid++, getpid());
2018-06-06 04:18:17 +00:00
c->wctx = g_main_context_new();
c->loop = g_main_loop_new(c->wctx, true);
c->watch = ipcwatch(CLIDIR, c->pid, c->wctx, c);
c->pppath = ipcpath( CLIDIR, c->pid);
2018-06-06 15:59:42 +00:00
g_mutex_lock(&rmm);
rmpath = g_slist_prepend(rmpath, c->pppath);
2018-06-06 15:59:42 +00:00
g_mutex_unlock(&rmm);
2018-06-06 04:18:17 +00:00
g_thread_unref(g_thread_new("wait", (GThreadFunc)g_main_loop_run, c->loop));
2018-06-06 04:18:17 +00:00
return c;
2018-06-05 09:34:05 +00:00
}
static void freecl(Client *c)
2018-06-05 09:34:05 +00:00
{
g_main_loop_quit(c->loop);
g_source_unref(c->watch);
g_main_loop_unref(c->loop);
g_main_context_unref(c->wctx);
g_mutex_clear(&c->retm);
g_free(c->pid);
g_free(c->retdata);
remove(c->pppath);
2018-06-06 15:59:42 +00:00
g_mutex_lock(&rmm);
rmpath = g_slist_remove(rmpath, c->pppath);
2018-06-06 15:59:42 +00:00
g_mutex_unlock(&rmm);
g_free(c->pppath);
2018-12-16 10:30:13 +00:00
g_free(c);
2018-06-05 09:34:05 +00:00
}
static Client *getcl()
2018-06-05 09:34:05 +00:00
{
static GMutex m;
g_mutex_lock(&m);
2018-06-26 06:13:32 +00:00
static GPrivate pc = G_PRIVATE_INIT((GDestroyNotify)freecl);
Client *c = g_private_get(&pc);
2018-06-26 06:13:32 +00:00
if (!c)
2018-06-05 09:34:05 +00:00
{
c = makecl();
g_private_set(&pc, c);
2018-06-05 09:34:05 +00:00
}
g_mutex_unlock(&m);
return c;
2018-05-19 15:51:50 +00:00
}
2019-09-28 13:54:36 +00:00
static GHashTable *lastsec;
2018-06-05 09:34:05 +00:00
static GMutex lastm;
static void setsec(char *exe, int sec)
2018-05-19 15:51:50 +00:00
{
2018-06-05 09:34:05 +00:00
g_mutex_lock(&lastm);
if (!lastsec) lastsec = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
g_hash_table_replace(lastsec, g_strdup(exe), g_strdup_printf("%d", sec));
g_mutex_unlock(&lastm);
}
static char *keepstr(char *exe)
{
g_mutex_lock(&lastm);
char *ret = g_hash_table_lookup(lastsec, exe);
g_mutex_unlock(&lastm);
2018-05-19 15:51:50 +00:00
2018-06-05 09:34:05 +00:00
#define Z(v) #v
return ret ?: Z(KEEPS);
#undef Z
2018-05-19 15:51:50 +00:00
}
2018-06-05 09:34:05 +00:00
static gboolean pingloop(Client *c)
2018-05-19 15:51:50 +00:00
{
if (!ipcsend(c->exe, PING, CSping, c->pid, keepstr(c->exe)))
g_mutex_unlock(&c->retm);
2018-05-19 15:51:50 +00:00
return true;
}
static gboolean timeoutcb(Client *c)
2018-05-19 15:51:50 +00:00
{
g_mutex_unlock(&c->retm);
2018-05-19 15:51:50 +00:00
return false;
}
//don't free
2018-06-05 09:34:05 +00:00
static char *request(char *exe, Com type, bool caller, char *data)
2018-05-19 15:51:50 +00:00
{
Client *c = getcl();
2018-05-19 15:51:50 +00:00
if (caller)
2018-06-05 09:34:05 +00:00
{
g_mutex_lock(&c->retm);
g_free(c->retdata);
c->retdata = NULL;
2018-06-05 09:34:05 +00:00
}
2018-05-19 15:51:50 +00:00
if (!ipcsend(exe, INPUT, type, caller ? c->pid : NULL, data))
2018-05-19 15:51:50 +00:00
{ //svr is not running
char *path = ipcpath(exe, "lock");
if (!g_file_test(path, G_FILE_TEST_EXISTS))
mkdirif(path);
int lock = open(path, O_RDONLY | O_CREAT, S_IRUSR);
g_free(path);
2018-05-29 16:00:21 +00:00
flock(lock, LOCK_EX);
2018-05-19 15:51:50 +00:00
//retry in single proc
if (!ipcsend(exe, INPUT, type, caller ? c->pid : NULL, data))
2018-05-19 15:51:50 +00:00
{
if (!caller)
g_mutex_lock(&c->retm);
2018-06-05 09:34:05 +00:00
GSource *tout = g_timeout_source_new(KEEPS * 1000);
g_source_set_callback(tout, (GSourceFunc)timeoutcb, c, NULL);
g_source_attach(tout, c->wctx);
2018-06-05 09:34:05 +00:00
2018-05-19 15:51:50 +00:00
2018-06-08 13:37:36 +00:00
char **argv = g_new0(char*, 4);
2018-06-05 09:34:05 +00:00
argv[0] = exe;
2018-06-08 13:37:36 +00:00
argv[1] = PREFIX;
argv[2] = c->pid;
2018-06-05 09:34:05 +00:00
GError *err = NULL;
if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
NULL, NULL, NULL, &err))
{
g_print("err %s", err->message);
g_error_free(err);
}
g_free(argv);
2018-05-19 15:51:50 +00:00
2018-06-05 09:34:05 +00:00
g_mutex_lock(&c->retm);
g_mutex_unlock(&c->retm);
2018-05-19 15:51:50 +00:00
g_source_destroy(tout);
g_source_unref(tout);
//wyebloop doesn't know svr quits
2018-06-05 09:34:05 +00:00
wyebkeep(exe, 0);
2018-05-19 15:51:50 +00:00
if (caller)
g_mutex_lock(&c->retm);
if (!ipcsend(exe, INPUT, type, caller ? c->pid : NULL, data))
2018-06-07 05:29:52 +00:00
P(Spawning %s failed !!, exe)
2018-05-19 15:51:50 +00:00
}
close(lock);
}
if (caller)
{
GSource *ping = g_timeout_source_new(DPINGTIME);
c->exe = exe;
g_source_set_callback(ping, (GSourceFunc)pingloop, c, NULL);
g_source_attach(ping, c->wctx); //attach to ping thread
2018-05-19 15:51:50 +00:00
g_mutex_lock(&c->retm);
g_mutex_unlock(&c->retm);
2018-05-19 15:51:50 +00:00
g_source_destroy(ping);
g_source_unref(ping);
}
return c->retdata;
2018-05-19 15:51:50 +00:00
}
2018-06-05 09:34:05 +00:00
char *wyebget(char *exe, char *data)
2018-05-20 01:19:51 +00:00
{
2018-06-05 09:34:05 +00:00
return request(exe, CSdata, true, data);
2018-05-20 01:19:51 +00:00
}
2018-06-05 09:34:05 +00:00
void wyebsend(char *exe, char *data)
2018-05-22 05:24:54 +00:00
{
2018-06-05 09:34:05 +00:00
request(exe, CSdata, false, data);
2018-05-22 05:24:54 +00:00
}
2018-06-05 09:34:05 +00:00
static gboolean keepcb(char *exe)
2018-05-19 15:51:50 +00:00
{
2018-06-05 09:34:05 +00:00
request(exe, CSuntil, false, keepstr(exe));
2018-05-22 05:24:54 +00:00
return false;
}
2018-06-05 09:34:05 +00:00
void wyebkeep(char *exe, int sec)
2018-05-19 15:51:50 +00:00
{
2018-06-05 09:34:05 +00:00
if (sec) setsec(exe, sec);
g_idle_add_full(G_PRIORITY_DEFAULT, (GSourceFunc)keepcb,
g_strdup(exe), g_free);
2018-05-19 15:51:50 +00:00
}
2018-05-22 05:24:54 +00:00
2018-06-05 09:34:05 +00:00
static gboolean loopcb(char *exe)
2018-05-19 15:51:50 +00:00
{
2018-06-05 09:34:05 +00:00
keepcb(exe);
2018-05-19 15:51:50 +00:00
return true;
}
2018-06-05 09:34:05 +00:00
guint wyebloop(char *exe, int sec)
2018-05-19 15:51:50 +00:00
{
2018-06-05 09:34:05 +00:00
if (sec) setsec(exe, sec);
loopcb(exe);
return g_timeout_add_full(G_PRIORITY_DEFAULT, sec * 300,
(GSourceFunc)loopcb, g_strdup(exe), g_free);
2018-05-19 15:51:50 +00:00
}
2018-06-05 09:34:05 +00:00
2018-06-23 05:31:24 +00:00
#if TESTER
2018-06-05 09:34:05 +00:00
static void testget(gpointer p, gpointer ap)
{
2018-06-26 06:13:32 +00:00
// P(ret %s - %s, wyebget(ap, p), (char *)p)
wyebget(ap, p);
2018-06-05 09:34:05 +00:00
g_free(p);
}
#endif
static gboolean tcinputcb(GIOChannel *ch, GIOCondition cnd, char *exe)
2018-05-19 15:51:50 +00:00
{
char *line;
if (cnd == G_IO_HUP || G_IO_STATUS_EOF ==
2018-05-29 06:06:35 +00:00
g_io_channel_read_line(ch, &line, NULL, NULL, NULL))
2018-05-29 05:57:19 +00:00
exit(0);
2018-05-19 15:51:50 +00:00
if (!line) return true;
g_strstrip(line);
if (!strlen(line))
exit(0);
2018-06-23 05:31:24 +00:00
#if TESTER
2018-05-22 03:02:56 +00:00
if (g_str_has_prefix(line, "l"))
2018-05-19 15:51:50 +00:00
{
2018-06-26 06:13:32 +00:00
GThreadPool *pool = g_thread_pool_new(testget, exe, 32, false, NULL);
2018-06-05 09:34:05 +00:00
2018-06-23 05:31:24 +00:00
gint64 start = g_get_monotonic_time();
for (int i = 0; i < 100000; i++)
2018-05-19 15:51:50 +00:00
{
char *is = g_strdup_printf("l%d", i);
2018-06-05 09:34:05 +00:00
//g_print("loop %d ret %s\n", i, wyebget(exe, is));
2018-05-22 03:02:56 +00:00
if (*(line + 1) == 's')
wyebsend(exe, is);
else if (*(line + 1) == 'p')
D(pint %s, is)
2018-06-07 09:20:03 +00:00
else if (*(line + 1) == 'c')
{
gchar *data;
g_spawn_command_line_sync("echo 'ret'", &data, NULL, NULL, NULL);
g_strchomp(data);
D(cmd %s %s, is, data)
g_free(data);
}
2018-05-22 03:02:56 +00:00
else
2018-06-23 05:31:24 +00:00
{
2018-06-05 09:34:05 +00:00
// wyebget(exe, is);
2018-06-23 05:31:24 +00:00
g_thread_pool_push(pool, is, NULL);
is = NULL;
}
2018-06-07 09:20:03 +00:00
2018-05-19 15:51:50 +00:00
g_free(is);
}
2018-06-05 09:34:05 +00:00
g_thread_pool_free(pool, false, true);
2018-05-19 15:51:50 +00:00
gint64 now = g_get_monotonic_time();
2018-06-23 05:31:24 +00:00
P(time %f, (now - start) / 1000000.0)
2018-05-19 15:51:50 +00:00
}
else
#endif
2018-06-07 09:20:03 +00:00
P(%s, wyebget(exe, line))
2018-05-19 15:51:50 +00:00
g_free(line);
return true;
}
static gboolean tcinit(char *exe)
{
2018-06-04 20:54:27 +00:00
#if DEBUG
2018-06-05 09:34:05 +00:00
wyebloop(exe, 300);
2018-06-04 20:54:27 +00:00
#else
2018-06-05 09:34:05 +00:00
wyebloop(exe, 2);
2018-06-04 20:54:27 +00:00
#endif
2018-05-19 15:51:50 +00:00
GIOChannel *io = g_io_channel_unix_new(fileno(stdin));
2018-05-29 06:06:35 +00:00
g_io_add_watch(io, G_IO_IN | G_IO_HUP, (GIOFunc)tcinputcb, exe);
2018-05-19 15:51:50 +00:00
return false;
}
void wyebclient(char *exe)
{
2018-06-05 09:34:05 +00:00
GMainLoop *loop = g_main_loop_new(NULL, false);
2018-05-19 15:51:50 +00:00
g_idle_add((GSourceFunc)tcinit, exe);
2018-06-05 09:34:05 +00:00
g_main_loop_run(loop);
2018-05-19 15:51:50 +00:00
}
//@ipccb
gboolean ipccb(GIOChannel *ch, GIOCondition cnd, gpointer p)
2018-05-19 15:51:50 +00:00
{
//D(ipccb %c, svrexe ? 'S':'C')
2018-05-19 15:51:50 +00:00
char *line;
g_io_channel_read_line(ch, &line, NULL, NULL, NULL);
if (!line) return true;
2018-06-06 04:18:17 +00:00
Com type = *line;
char *id = line + 1;
char *data = strchr(line, ':');
2018-06-05 09:34:05 +00:00
*data++ = '\0';
2018-06-06 04:18:17 +00:00
g_strchomp(data);
2018-05-19 15:51:50 +00:00
#if DEBUG
2019-09-28 13:54:36 +00:00
static int i;
D(%c ipccb%d %c/%s/%lu;, svrexe ? 'S':'C', i++, type ,id, strlen(data))
2018-05-19 15:51:50 +00:00
#endif
switch (type) {
//server
case CSdata:
2018-06-04 20:54:27 +00:00
{
Dataargs *args = g_new(Dataargs, 1);
args->caller = g_strdup(id);
2018-06-06 04:18:17 +00:00
args->data = g_strcompress(data);
2018-06-05 09:34:05 +00:00
2019-09-28 13:54:36 +00:00
static GThreadPool *pool;
2018-06-05 09:34:05 +00:00
if (!pool) pool = g_thread_pool_new(getdata, NULL, -1, false, NULL);
g_thread_pool_push(pool, args, NULL);
2018-05-19 15:51:50 +00:00
break;
2018-06-04 20:54:27 +00:00
}
2018-05-19 15:51:50 +00:00
case CSping:
2018-06-04 20:54:27 +00:00
g_mutex_lock(&ordersm);
2018-05-19 15:51:50 +00:00
if (!g_hash_table_lookup(orders, id))
2018-06-05 09:34:05 +00:00
ipcsend(CLIDIR, id, CClost, NULL, NULL);
2018-06-04 20:54:27 +00:00
g_mutex_unlock(&ordersm);
2018-06-05 09:34:05 +00:00
case CSuntil:
until(atoi(data));
2018-05-19 15:51:50 +00:00
break;
//client
case CCret:
case CClost:
case CCwoke:
2018-06-05 09:34:05 +00:00
{
Client *c = p;
2018-06-05 09:34:05 +00:00
if (type == CCret)
c->retdata = g_strcompress(data);
2018-06-05 09:34:05 +00:00
2018-06-04 20:54:27 +00:00
//for the case pinging at same time of ret
g_mutex_trylock(&c->retm);
g_mutex_unlock(&c->retm);
2018-06-26 06:13:32 +00:00
g_thread_yield();
2018-05-19 15:51:50 +00:00
break;
}
2018-06-05 09:34:05 +00:00
}
2018-05-19 15:51:50 +00:00
2018-06-06 04:18:17 +00:00
g_free(line);
2018-05-19 15:51:50 +00:00
return true;
}
//test
#if TESTER
2018-06-05 09:34:05 +00:00
static char *testdata(char *data)
2018-05-19 15:51:50 +00:00
{
//sleep(9);
2018-06-05 09:34:05 +00:00
//g_free(data); //makes crash
2018-05-19 15:51:50 +00:00
2019-09-28 13:54:36 +00:00
static int i;
2018-06-05 09:34:05 +00:00
return g_strdup_printf("%d th test data. req is %s", ++i, data);
2018-05-19 15:51:50 +00:00
}
int main(int argc, char **argv)
{
2018-06-23 05:31:24 +00:00
// start = g_get_monotonic_time();
2018-05-19 15:51:50 +00:00
// gint64 now = g_get_monotonic_time();
// D(time %ld %ld, now - start, now)
if (!wyebsvr(argc, argv, testdata))
wyebclient(argv[0]);
exit(0);
}
#endif