--- libaitio/src/sock.c 2013/12/03 18:58:22 1.11 +++ libaitio/src/sock.c 2013/12/15 22:57:20 1.12 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: sock.c,v 1.11 2013/12/03 18:58:22 misho Exp $ +* $Id: sock.c,v 1.12 2013/12/15 22:57:20 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -61,6 +61,14 @@ io_closeClient(sched_task_t *task) if (*cli->cli_name) ioFreePTY(cli->cli_pty, cli->cli_name); + if (s->sock_prog) { + io_progDetach(s->sock_prog, cli->cli_pty); +#if 0 + io_progCloseAt(s->sock_prog, cli->cli_pty); +#endif + cli->cli_pty ^= cli->cli_pty; + io_progCheck(s->sock_prog, 42); + } if (s->sock_type == SOCK_STREAM) { shutdown(cli->cli_fd, SHUT_RDWR); @@ -149,8 +157,10 @@ io_txNet(sched_task_t *task) if ((ret = poll(pfd, 1, s->sock_timeout.tv_sec * 1000)) < 1 || pfd->revents & (POLLNVAL | POLLERR | POLLHUP)) { +#if 0 if (!ret) continue; +#endif schedEvent(TASK_ROOT(task), io_closeClient, cli, 0, NULL, 0); break; } @@ -311,7 +321,62 @@ end: taskExit(task, NULL); } +static void * +io_bridgeClient2Pool(sched_task_t *task) +{ + int c, rlen; + sockaddr_t sa; + socklen_t salen = sizeof sa.ss; + sock_cli_t *cli = NULL; + sock_t *s = (sock_t*) TASK_ARG(task); + if (s->sock_type == SOCK_STREAM) { + if ((c = accept(TASK_FD(task), &sa.sa, &salen)) == -1) { + LOGERR; + goto end; + } + } else { + if ((rlen = recvfrom(TASK_FD(task), + AIT_GET_BUF(&s->sock_buf), AIT_LEN(&s->sock_buf), + MSG_PEEK, &sa.sa, &salen)) == -1) { + LOGERR; + goto end; + } else + c = TASK_FD(task); + } + + cli = e_malloc(sizeof(sock_cli_t)); + if (!cli) { + io_SetErr(elwix_GetErrno(), "%s", elwix_GetError()); + if (s->sock_type == SOCK_STREAM) + close(c); + goto end; + } else { + memset(cli, 0, sizeof(sock_cli_t)); + pthread_mutex_lock(&s->sock_mtx); + TAILQ_INSERT_TAIL(&s->sock_cli, cli, cli_node); + pthread_mutex_unlock(&s->sock_mtx); + } + + io_progCheck(s->sock_prog, 42); + + cli->cli_parent = TASK_ARG(task); + cli->cli_fd = c; + cli->cli_pty = io_progAttach(s->sock_prog, 42); + strlcpy(cli->cli_cmdline, TASK_DATA(task), sizeof cli->cli_cmdline); + memcpy(&cli->cli_addr, &sa, sizeof cli->cli_addr); + AIT_SET_BUFSIZ(&cli->cli_buf[0], 0, AIT_LEN(&s->sock_buf)); + AIT_SET_BUFSIZ(&cli->cli_buf[1], 0, AIT_LEN(&s->sock_buf)); + + schedRead(TASK_ROOT(task), io_rxPty, cli, cli->cli_pty, TASK_ARG(task), 0); + schedRead(TASK_ROOT(task), io_rxNet, cli, cli->cli_fd, TASK_ARG(task), 0); + ioUpdTimerSocket(cli); +end: + schedReadSelf(task); + taskExit(task, NULL); +} + + /* * ioInitSocket() - Init socket and allocate resources * @@ -517,6 +582,9 @@ ioUpdTimerSocket(sock_cli_t * __restrict c) else s = c->cli_parent; + if (s->sock_prog) + io_progCheck(s->sock_prog, 42); + schedCancelby(s->sock_root, taskTIMER, CRITERIA_ARG, c, NULL); schedTimer(s->sock_root, io_closeClient, c, s->sock_timeout, NULL, 0); } @@ -557,6 +625,18 @@ ioLoopSocket(sock_t * __restrict s, sched_task_func_t return schedRun(s->sock_root, &s->sock_kill); } +static void * +io_progPurge(sched_task_t *task) +{ + sock_t *s = (sock_t*) TASK_ARG(task); + + io_progVacuum(s->sock_prog, 0); + + schedTimer(TASK_ROOT(task), TASK_FUNC(task), TASK_ARG(task), + s->sock_timeout, TASK_DATA(task), TASK_DATLEN(task)); + taskExit(task, NULL); +} + /* * ioBridgeProg2Socket() - Start socket scheduler and bridge program to socket * @@ -570,6 +650,29 @@ ioBridgeProg2Socket(sock_t * __restrict s, const char if (!s || !prgname || s->sock_kill) return -1; - schedRead(s->sock_root, io_bridgeClient, s, s->sock_fd, (void*) prgname, 0); + if (s->sock_prog) { + schedRead(s->sock_root, io_bridgeClient2Pool, + s, s->sock_fd, (void*) prgname, 0); + schedTimer(s->sock_root, io_progPurge, s, s->sock_timeout, NULL, 0); + } else + schedRead(s->sock_root, io_bridgeClient, + s, s->sock_fd, (void*) prgname, 0); return schedRun(s->sock_root, &s->sock_kill); +} + +/* + * ioSetupProg2Socket() - Setup program pool to socket server + * + * @s = Socket + * @p = Program pool + * return: -1 error or 0 ok + */ +int +ioSetupProg2Socket(sock_t * __restrict s, prog_t * __restrict p) +{ + if (!s) + return -1; + + s->sock_prog = p; + return 0; }