Message ID | 20191217075055.3172-1-christian.storm@siemens.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/3] IPC: factor out pthread-based methods | expand |
Hi Christian, On 17/12/19 08:50, Christian Storm wrote: > Factor out the pthread-based IPC interface methods described in > swupdate-ipc.rst, Section "Client Library", into a separate > compilation unit ipc/network_ipc-if.c, leaving the "plumbing" > methods in ipc/network_ipc.c. > > This allows, e.g., the Lua shared library binding to use the > "plumbing" methods while not pulling in the pthread dependency. > > Signed-off-by: Christian Storm <christian.storm@siemens.com> > --- > ipc/Makefile | 2 +- > ipc/network_ipc-if.c | 146 ++++++++++++++++++++++++++++++++++++++++++ > ipc/network_ipc.c | 147 ------------------------------------------- > 3 files changed, 147 insertions(+), 148 deletions(-) > create mode 100644 ipc/network_ipc-if.c > > diff --git a/ipc/Makefile b/ipc/Makefile > index e2826bd..5c12d3d 100644 > --- a/ipc/Makefile > +++ b/ipc/Makefile > @@ -1,6 +1,6 @@ > # Copyright (C) 2014-2018 Stefano Babic <sbabic@denx.de> > # > # SPDX-License-Identifier: GPL-2.0-or-later > -lib-y += network_ipc.o progress_ipc.o > +lib-y += network_ipc.o network_ipc-if.o progress_ipc.o > > EXTRA_CFLAGS += -fPIC > diff --git a/ipc/network_ipc-if.c b/ipc/network_ipc-if.c > new file mode 100644 > index 0000000..fcfad6e > --- /dev/null > +++ b/ipc/network_ipc-if.c > @@ -0,0 +1,146 @@ > +/* > + * Author: Christian Storm > + * Copyright (C) 2019, Siemens AG > + * This is just a move of code into a separate file - Copyright should be maintained from original. Regards, Stefano > + * SPDX-License-Identifier: LGPL-2.1-or-later > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <errno.h> > +#include <signal.h> > +#include <pthread.h> > +#include "network_ipc.h" > + > +static pthread_t async_thread_id; > + > +struct async_lib { > + int connfd; > + int status; > + writedata wr; > + getstatus get; > + terminated end; > +}; > + > +static int handle = 0; > + > +static struct async_lib request; > + > +#define get_request() (&request) > + > +static void *swupdate_async_thread(void *data) > +{ > + char *pbuf; > + int size; > + sigset_t sigpipe_mask; > + sigset_t saved_mask; > + struct timespec zerotime = {0, 0}; > + struct async_lib *rq = (struct async_lib *)data; > + int swupdate_result; > + > + sigemptyset(&sigpipe_mask); > + sigaddset(&sigpipe_mask, SIGPIPE); > + > + if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) { > + perror("pthread_sigmask"); > + exit(1); > + } > + /* Start writing the image until end */ > + > + do { > + if (!rq->wr) > + break; > + > + rq->wr(&pbuf, &size); > + if (size) > + swupdate_image_write(pbuf, size); > + } while(size > 0); > + > + ipc_end(rq->connfd); > + printf("Now getting status\n"); > + > + /* > + * Everything sent, ask for status > + */ > + > + swupdate_result = ipc_wait_for_complete(rq->get); > + > + handle = 0; > + > + if (sigtimedwait(&sigpipe_mask, 0, &zerotime) == -1) { > + // currently ignored > + } > + > + if (pthread_sigmask(SIG_SETMASK, &saved_mask, 0) == -1) { > + perror("pthread_sigmask"); > + } > + > + if (rq->end) > + rq->end((RECOVERY_STATUS)swupdate_result); > + > + pthread_exit(NULL); > +} > + > +/* > + * This is duplicated from pctl > + * to let build the ipc library without > + * linking pctl code > + */ > +static pthread_t start_ipc_thread(void *(* start_routine) (void *), void *arg) > +{ > + int ret; > + pthread_t id; > + pthread_attr_t attr; > + > + pthread_attr_init(&attr); > + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); > + > + ret = pthread_create(&id, &attr, start_routine, arg); > + if (ret) { > + exit(1); > + } > + return id; > +} > + > +/* > + * This is part of the library for an external client. > + * Only one running request is accepted > + */ > +int swupdate_async_start(writedata wr_func, getstatus status_func, > + terminated end_func, bool dryrun) > +{ > + struct async_lib *rq; > + int connfd; > + > + if (handle) > + return -EBUSY; > + > + rq = get_request(); > + > + rq->wr = wr_func; > + rq->get = status_func; > + rq->end = end_func; > + > + connfd = ipc_inst_start_ext(SOURCE_UNKNOWN, 0, NULL, dryrun); > + > + if (connfd < 0) > + return connfd; > + > + rq->connfd = connfd; > + > + async_thread_id = start_ipc_thread(swupdate_async_thread, rq); > + > + handle++; > + > + return handle; > +} > + > +int swupdate_image_write(char *buf, int size) > +{ > + struct async_lib *rq; > + > + rq = get_request(); > + > + return ipc_send_data(rq->connfd, buf, size); > +} > + > diff --git a/ipc/network_ipc.c b/ipc/network_ipc.c > index 53e577d..9cfb877 100644 > --- a/ipc/network_ipc.c > +++ b/ipc/network_ipc.c > @@ -9,26 +9,9 @@ > #include <stdio.h> > #include <stdlib.h> > #include <unistd.h> > -#include <string.h> > -#include <getopt.h> > -#include <errno.h> > -#include <signal.h> > -#include <sys/ioctl.h> > -#include <fcntl.h> > -#include <sys/types.h> > #include <sys/socket.h> > #include <sys/un.h> > -#include <arpa/inet.h> > -#include <netinet/in.h> > -#include <sys/stat.h> > -#include <ctype.h> > -#include <fcntl.h> > -#include <sys/select.h> > -#include <errno.h> > -#include <pthread.h> > - > #include "network_ipc.h" > -#include "compat.h" > > #ifdef CONFIG_SOCKET_CTRL_PATH > static char* SOCKET_CTRL_PATH = (char*)CONFIG_SOCKET_CTRL_PATH; > @@ -38,20 +21,6 @@ static char* SOCKET_CTRL_PATH = NULL; > > #define SOCKET_CTRL_DEFAULT "sockinstctrl" > > -struct async_lib { > - int connfd; > - int status; > - writedata wr; > - getstatus get; > - terminated end; > -}; > - > -static int handle = 0; > -static struct async_lib request; > -static pthread_t async_thread_id; > - > -#define get_request() (&request) > - > char *get_ctrl_socket(void) { > if (!SOCKET_CTRL_PATH || !strlen(SOCKET_CTRL_PATH)) { > const char *tmpdir = getenv("TMPDIR"); > @@ -241,15 +210,6 @@ void ipc_end(int connfd) > close(connfd); > } > > -int swupdate_image_write(char *buf, int size) > -{ > - struct async_lib *rq; > - > - rq = get_request(); > - > - return ipc_send_data(rq->connfd, buf, size); > -} > - > int ipc_wait_for_complete(getstatus callback) > { > int fd; > @@ -283,113 +243,6 @@ int ipc_wait_for_complete(getstatus callback) > return message.data.status.last_result; > } > > -static void *swupdate_async_thread(void *data) > -{ > - char *pbuf; > - int size; > - sigset_t sigpipe_mask; > - sigset_t saved_mask; > - struct timespec zerotime = {0, 0}; > - struct async_lib *rq = (struct async_lib *)data; > - int swupdate_result; > - > - sigemptyset(&sigpipe_mask); > - sigaddset(&sigpipe_mask, SIGPIPE); > - > - if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) { > - perror("pthread_sigmask"); > - exit(1); > - } > - /* Start writing the image until end */ > - > - do { > - if (!rq->wr) > - break; > - > - rq->wr(&pbuf, &size); > - if (size) > - swupdate_image_write(pbuf, size); > - } while(size > 0); > - > - ipc_end(rq->connfd); > - printf("Now getting status\n"); > - > - /* > - * Everything sent, ask for status > - */ > - > - swupdate_result = ipc_wait_for_complete(rq->get); > - > - handle = 0; > - > - if (sigtimedwait(&sigpipe_mask, 0, &zerotime) == -1) { > - // currently ignored > - } > - > - if (pthread_sigmask(SIG_SETMASK, &saved_mask, 0) == -1) { > - perror("pthread_sigmask"); > - } > - > - if (rq->end) > - rq->end((RECOVERY_STATUS)swupdate_result); > - > - pthread_exit(NULL); > -} > - > -/* > - * This is duplicated from pctl > - * to let build the ipc library without > - * linking pctl code > - */ > -static pthread_t start_ipc_thread(void *(* start_routine) (void *), void *arg) > -{ > - int ret; > - pthread_t id; > - pthread_attr_t attr; > - > - pthread_attr_init(&attr); > - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); > - > - ret = pthread_create(&id, &attr, start_routine, arg); > - if (ret) { > - exit(1); > - } > - return id; > -} > - > -/* > - * This is part of the library for an external client. > - * Only one running request is accepted > - */ > -int swupdate_async_start(writedata wr_func, getstatus status_func, > - terminated end_func, bool dryrun) > -{ > - struct async_lib *rq; > - int connfd; > - > - if (handle) > - return -EBUSY; > - > - rq = get_request(); > - > - rq->wr = wr_func; > - rq->get = status_func; > - rq->end = end_func; > - > - connfd = ipc_inst_start_ext(SOURCE_UNKNOWN, 0, NULL, dryrun); > - > - if (connfd < 0) > - return connfd; > - > - rq->connfd = connfd; > - > - async_thread_id = start_ipc_thread(swupdate_async_thread, rq); > - > - handle++; > - > - return handle; > -} > - > int ipc_send_cmd(ipc_message *msg) > { > int connfd = prepare_ipc(); >
Hi Stefano, > On 17/12/19 08:50, Christian Storm wrote: > > Factor out the pthread-based IPC interface methods described in > > swupdate-ipc.rst, Section "Client Library", into a separate > > compilation unit ipc/network_ipc-if.c, leaving the "plumbing" > > methods in ipc/network_ipc.c. > > > > This allows, e.g., the Lua shared library binding to use the > > "plumbing" methods while not pulling in the pthread dependency. > > > > Signed-off-by: Christian Storm <christian.storm@siemens.com> > > --- > > ipc/Makefile | 2 +- > > ipc/network_ipc-if.c | 146 ++++++++++++++++++++++++++++++++++++++++++ > > ipc/network_ipc.c | 147 ------------------------------------------- > > 3 files changed, 147 insertions(+), 148 deletions(-) > > create mode 100644 ipc/network_ipc-if.c > > > > diff --git a/ipc/Makefile b/ipc/Makefile > > index e2826bd..5c12d3d 100644 > > --- a/ipc/Makefile > > +++ b/ipc/Makefile > > @@ -1,6 +1,6 @@ > > # Copyright (C) 2014-2018 Stefano Babic <sbabic@denx.de> > > # > > # SPDX-License-Identifier: GPL-2.0-or-later > > -lib-y += network_ipc.o progress_ipc.o > > +lib-y += network_ipc.o network_ipc-if.o progress_ipc.o > > > > EXTRA_CFLAGS += -fPIC > > diff --git a/ipc/network_ipc-if.c b/ipc/network_ipc-if.c > > new file mode 100644 > > index 0000000..fcfad6e > > --- /dev/null > > +++ b/ipc/network_ipc-if.c > > @@ -0,0 +1,146 @@ > > +/* > > + * Author: Christian Storm > > + * Copyright (C) 2019, Siemens AG > > + * > > This is just a move of code into a separate file - Copyright should be > maintained from original. Yes, it is, you're right. Will keep the original header in v2... Kind regards, Christian
diff --git a/ipc/Makefile b/ipc/Makefile index e2826bd..5c12d3d 100644 --- a/ipc/Makefile +++ b/ipc/Makefile @@ -1,6 +1,6 @@ # Copyright (C) 2014-2018 Stefano Babic <sbabic@denx.de> # # SPDX-License-Identifier: GPL-2.0-or-later -lib-y += network_ipc.o progress_ipc.o +lib-y += network_ipc.o network_ipc-if.o progress_ipc.o EXTRA_CFLAGS += -fPIC diff --git a/ipc/network_ipc-if.c b/ipc/network_ipc-if.c new file mode 100644 index 0000000..fcfad6e --- /dev/null +++ b/ipc/network_ipc-if.c @@ -0,0 +1,146 @@ +/* + * Author: Christian Storm + * Copyright (C) 2019, Siemens AG + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <signal.h> +#include <pthread.h> +#include "network_ipc.h" + +static pthread_t async_thread_id; + +struct async_lib { + int connfd; + int status; + writedata wr; + getstatus get; + terminated end; +}; + +static int handle = 0; + +static struct async_lib request; + +#define get_request() (&request) + +static void *swupdate_async_thread(void *data) +{ + char *pbuf; + int size; + sigset_t sigpipe_mask; + sigset_t saved_mask; + struct timespec zerotime = {0, 0}; + struct async_lib *rq = (struct async_lib *)data; + int swupdate_result; + + sigemptyset(&sigpipe_mask); + sigaddset(&sigpipe_mask, SIGPIPE); + + if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) { + perror("pthread_sigmask"); + exit(1); + } + /* Start writing the image until end */ + + do { + if (!rq->wr) + break; + + rq->wr(&pbuf, &size); + if (size) + swupdate_image_write(pbuf, size); + } while(size > 0); + + ipc_end(rq->connfd); + printf("Now getting status\n"); + + /* + * Everything sent, ask for status + */ + + swupdate_result = ipc_wait_for_complete(rq->get); + + handle = 0; + + if (sigtimedwait(&sigpipe_mask, 0, &zerotime) == -1) { + // currently ignored + } + + if (pthread_sigmask(SIG_SETMASK, &saved_mask, 0) == -1) { + perror("pthread_sigmask"); + } + + if (rq->end) + rq->end((RECOVERY_STATUS)swupdate_result); + + pthread_exit(NULL); +} + +/* + * This is duplicated from pctl + * to let build the ipc library without + * linking pctl code + */ +static pthread_t start_ipc_thread(void *(* start_routine) (void *), void *arg) +{ + int ret; + pthread_t id; + pthread_attr_t attr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + ret = pthread_create(&id, &attr, start_routine, arg); + if (ret) { + exit(1); + } + return id; +} + +/* + * This is part of the library for an external client. + * Only one running request is accepted + */ +int swupdate_async_start(writedata wr_func, getstatus status_func, + terminated end_func, bool dryrun) +{ + struct async_lib *rq; + int connfd; + + if (handle) + return -EBUSY; + + rq = get_request(); + + rq->wr = wr_func; + rq->get = status_func; + rq->end = end_func; + + connfd = ipc_inst_start_ext(SOURCE_UNKNOWN, 0, NULL, dryrun); + + if (connfd < 0) + return connfd; + + rq->connfd = connfd; + + async_thread_id = start_ipc_thread(swupdate_async_thread, rq); + + handle++; + + return handle; +} + +int swupdate_image_write(char *buf, int size) +{ + struct async_lib *rq; + + rq = get_request(); + + return ipc_send_data(rq->connfd, buf, size); +} + diff --git a/ipc/network_ipc.c b/ipc/network_ipc.c index 53e577d..9cfb877 100644 --- a/ipc/network_ipc.c +++ b/ipc/network_ipc.c @@ -9,26 +9,9 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <string.h> -#include <getopt.h> -#include <errno.h> -#include <signal.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/stat.h> -#include <ctype.h> -#include <fcntl.h> -#include <sys/select.h> -#include <errno.h> -#include <pthread.h> - #include "network_ipc.h" -#include "compat.h" #ifdef CONFIG_SOCKET_CTRL_PATH static char* SOCKET_CTRL_PATH = (char*)CONFIG_SOCKET_CTRL_PATH; @@ -38,20 +21,6 @@ static char* SOCKET_CTRL_PATH = NULL; #define SOCKET_CTRL_DEFAULT "sockinstctrl" -struct async_lib { - int connfd; - int status; - writedata wr; - getstatus get; - terminated end; -}; - -static int handle = 0; -static struct async_lib request; -static pthread_t async_thread_id; - -#define get_request() (&request) - char *get_ctrl_socket(void) { if (!SOCKET_CTRL_PATH || !strlen(SOCKET_CTRL_PATH)) { const char *tmpdir = getenv("TMPDIR"); @@ -241,15 +210,6 @@ void ipc_end(int connfd) close(connfd); } -int swupdate_image_write(char *buf, int size) -{ - struct async_lib *rq; - - rq = get_request(); - - return ipc_send_data(rq->connfd, buf, size); -} - int ipc_wait_for_complete(getstatus callback) { int fd; @@ -283,113 +243,6 @@ int ipc_wait_for_complete(getstatus callback) return message.data.status.last_result; } -static void *swupdate_async_thread(void *data) -{ - char *pbuf; - int size; - sigset_t sigpipe_mask; - sigset_t saved_mask; - struct timespec zerotime = {0, 0}; - struct async_lib *rq = (struct async_lib *)data; - int swupdate_result; - - sigemptyset(&sigpipe_mask); - sigaddset(&sigpipe_mask, SIGPIPE); - - if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) { - perror("pthread_sigmask"); - exit(1); - } - /* Start writing the image until end */ - - do { - if (!rq->wr) - break; - - rq->wr(&pbuf, &size); - if (size) - swupdate_image_write(pbuf, size); - } while(size > 0); - - ipc_end(rq->connfd); - printf("Now getting status\n"); - - /* - * Everything sent, ask for status - */ - - swupdate_result = ipc_wait_for_complete(rq->get); - - handle = 0; - - if (sigtimedwait(&sigpipe_mask, 0, &zerotime) == -1) { - // currently ignored - } - - if (pthread_sigmask(SIG_SETMASK, &saved_mask, 0) == -1) { - perror("pthread_sigmask"); - } - - if (rq->end) - rq->end((RECOVERY_STATUS)swupdate_result); - - pthread_exit(NULL); -} - -/* - * This is duplicated from pctl - * to let build the ipc library without - * linking pctl code - */ -static pthread_t start_ipc_thread(void *(* start_routine) (void *), void *arg) -{ - int ret; - pthread_t id; - pthread_attr_t attr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - ret = pthread_create(&id, &attr, start_routine, arg); - if (ret) { - exit(1); - } - return id; -} - -/* - * This is part of the library for an external client. - * Only one running request is accepted - */ -int swupdate_async_start(writedata wr_func, getstatus status_func, - terminated end_func, bool dryrun) -{ - struct async_lib *rq; - int connfd; - - if (handle) - return -EBUSY; - - rq = get_request(); - - rq->wr = wr_func; - rq->get = status_func; - rq->end = end_func; - - connfd = ipc_inst_start_ext(SOURCE_UNKNOWN, 0, NULL, dryrun); - - if (connfd < 0) - return connfd; - - rq->connfd = connfd; - - async_thread_id = start_ipc_thread(swupdate_async_thread, rq); - - handle++; - - return handle; -} - int ipc_send_cmd(ipc_message *msg) { int connfd = prepare_ipc();
Factor out the pthread-based IPC interface methods described in swupdate-ipc.rst, Section "Client Library", into a separate compilation unit ipc/network_ipc-if.c, leaving the "plumbing" methods in ipc/network_ipc.c. This allows, e.g., the Lua shared library binding to use the "plumbing" methods while not pulling in the pthread dependency. Signed-off-by: Christian Storm <christian.storm@siemens.com> --- ipc/Makefile | 2 +- ipc/network_ipc-if.c | 146 ++++++++++++++++++++++++++++++++++++++++++ ipc/network_ipc.c | 147 ------------------------------------------- 3 files changed, 147 insertions(+), 148 deletions(-) create mode 100644 ipc/network_ipc-if.c