aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSwarup Nayak <swarupnpvt@gmail.com>2018-09-04 17:26:26 +0530
committerSwarup Nayak <swarupnpvt@gmail.com>2018-09-17 10:41:35 +0000
commit0a5a2aadb7789251a2cba285e0a680951c5db573 (patch)
tree47792ac05182fe9f96945e95d2e87ec408f2c90e
parentfb84b14f79f186a624fcbb93c89d20df2978b41a (diff)
Feat: Fork support
Change-Id: Iae75c1c0bd4961ee052428bdd661d6f1da1bdbcb Signed-off-by: Swarup Nayak <swarupnpvt@gmail.com>
-rw-r--r--app_example/CMakeLists.txt2
-rw-r--r--app_example/func-test/CMakeLists.txt18
-rw-r--r--app_example/func-test/fork/CMakeLists.txt27
-rw-r--r--app_example/func-test/fork/tcpclient.c173
-rw-r--r--app_example/func-test/fork/tcpserver.c161
-rw-r--r--src/nSocket/include/nstack_dmm_api.h1
-rw-r--r--src/nSocket/include/nstack_select.h2
-rw-r--r--src/nSocket/kernel/linux_kernel_module.c1
-rw-r--r--src/nSocket/nstack/event/select/nstack_select.c22
-rw-r--r--src/nSocket/nstack/nstack.c2
-rw-r--r--src/nSocket/nstack/nstack_module.c20
-rw-r--r--src/nSocket/nstack/nstack_module.h1
-rw-r--r--src/nSocket/nstack/nstack_socket.c2
-rw-r--r--stacks/lwip_stack/lwip_src/api/spl_api_msg.c9
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_spl_share.h12
-rw-r--r--stacks/lwip_stack/lwip_src/core/spl_timers.c1
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c28
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h3
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c19
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c33
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h1
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_tcp.c2
-rw-r--r--stacks/lwip_stack/lwip_src/socket/stackx_udp.c2
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_protocol_api.h4
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_res_mgr.h31
-rw-r--r--stacks/lwip_stack/src/sbr/sbr_socket.c43
26 files changed, 613 insertions, 7 deletions
diff --git a/app_example/CMakeLists.txt b/app_example/CMakeLists.txt
index 0c88a4f..a82c752 100644
--- a/app_example/CMakeLists.txt
+++ b/app_example/CMakeLists.txt
@@ -15,4 +15,4 @@
#########################################################################
ADD_SUBDIRECTORY(perf-test)
-
+ADD_SUBDIRECTORY(func-test)
diff --git a/app_example/func-test/CMakeLists.txt b/app_example/func-test/CMakeLists.txt
new file mode 100644
index 0000000..e6357b8
--- /dev/null
+++ b/app_example/func-test/CMakeLists.txt
@@ -0,0 +1,18 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+
+ADD_SUBDIRECTORY(fork)
+
diff --git a/app_example/func-test/fork/CMakeLists.txt b/app_example/func-test/fork/CMakeLists.txt
new file mode 100644
index 0000000..266dd9f
--- /dev/null
+++ b/app_example/func-test/fork/CMakeLists.txt
@@ -0,0 +1,27 @@
+#########################################################################
+#
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -fPIC -m64 -mssse3 -std=gnu89")
+
+LINK_DIRECTORIES(${LIB_PATH_SHARED} ${LIB_PATH_STATIC})
+
+ADD_EXECUTABLE(tcp_fork_server tcpserver.c)
+ADD_DEPENDENCIES(tcp_fork_server nStackAPI)
+TARGET_LINK_LIBRARIES(tcp_fork_server libnStackAPI.so -lpthread -lrt)
+
+ADD_EXECUTABLE(tcp_client tcpclient.c)
+ADD_DEPENDENCIES(tcp_client nStackAPI)
+TARGET_LINK_LIBRARIES(tcp_client libnStackAPI.so -lpthread -lrt)
+
diff --git a/app_example/func-test/fork/tcpclient.c b/app_example/func-test/fork/tcpclient.c
new file mode 100644
index 0000000..274dcbb
--- /dev/null
+++ b/app_example/func-test/fork/tcpclient.c
@@ -0,0 +1,173 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt, arg...) do { \
+ printf(fmt, ##arg); \
+} while(0)
+#else
+#define DBG(fmt, arg...) ((void)0)
+#endif
+
+static struct sockaddr_in g_dest;
+static struct sockaddr_in g_src;
+int srcPort = 0;
+int destPort = 0;
+int times = 0;
+
+void
+random_str (char *str, const int len)
+{
+ static const char alphaNum[] =
+ "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789";
+ int i = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ str[i] = alphaNum[rand () % (sizeof (alphaNum) - 1)];
+ }
+
+ str[len] = 0;
+}
+
+static void
+setArgsDefault ()
+{
+
+ memset (&g_dest, 0, sizeof (g_dest));
+ g_dest.sin_family = AF_INET;
+ g_dest.sin_addr.s_addr = inet_addr ("127.0.0.1");
+ g_dest.sin_port = htons (12345);
+ bzero (&(g_dest.sin_zero), 8);
+
+ memset (&g_src, 0, sizeof (g_src));
+ g_src.sin_family = AF_INET;
+ g_src.sin_addr.s_addr = inet_addr ("0.0.0.0");
+ g_src.sin_port = htons (7895);
+ bzero (&(g_src.sin_zero), 8);
+
+ times = 1;
+}
+
+static int
+process_arg (int argc, char *argv[])
+{
+ int opt = 0;
+ int error = 0;
+ const char *optstring = "p:d:s:a:t:";
+
+ if (argc < 5)
+ {
+ DBG
+ ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -t times; \n");
+ return -1;
+ }
+ setArgsDefault ();
+ while ((opt = getopt (argc, argv, optstring)) != -1)
+ {
+ switch (opt)
+ {
+ case 'p':
+ g_dest.sin_port = htons (atoi (optarg));
+ break;
+ case 'd':
+ g_dest.sin_addr.s_addr = inet_addr (optarg);
+ break;
+ case 's':
+ g_src.sin_addr.s_addr = inet_addr (optarg);
+ break;
+ case 'a':
+ g_src.sin_port = htons (atoi (optarg));
+ break;
+ case 't':
+ times = atoi (optarg);
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+
+ int clientSocket, ret, i;
+ char sndbuffer[1024];
+ char rcvbuffer[1024];
+ int result = 0;
+
+ /*
+ * check command line arguments
+ */
+ if (0 != process_arg (argc, argv))
+ {
+ DBG ("Error in argument.%d\n", argc);
+ exit (1);
+ }
+
+ clientSocket = socket (AF_INET, SOCK_STREAM, 0);
+ if (clientSocket < 0)
+ {
+ DBG ("Error in connection.\n");
+ exit (1);
+ }
+ DBG ("[INFO]Client Socket is created.\n");
+
+ ret = bind (clientSocket, (struct sockaddr *) &g_src, sizeof (g_src));
+ if (ret < 0)
+ {
+ DBG ("Error in binding.\n");
+ exit (1);
+ }
+
+ DBG ("[INFO]Bind to client aaddress port 0\n");
+
+ ret = connect (clientSocket, (struct sockaddr *) &g_dest, sizeof (g_dest));
+ if (ret < 0)
+ {
+ DBG ("Error in connection.\n");
+ exit (1);
+ }
+ DBG ("[INFO]Connected to Server.\n");
+
+ memset (sndbuffer, '\0', 1024 * sizeof (char));
+ memset (rcvbuffer, '\0', 1024 * sizeof (char));
+
+ for (i = 1; i <= times; i++)
+ {
+ DBG ("Client: \t");
+ random_str (sndbuffer, 50);
+ send (clientSocket, sndbuffer, strlen (sndbuffer), 0);
+
+ if (recv (clientSocket, rcvbuffer, 1024, 0) < 0)
+ {
+ DBG ("Error in receiving data.\n");
+ }
+ else
+ {
+ DBG ("Server: \t%s\n", rcvbuffer);
+ }
+ if (0 != strcmp (sndbuffer, rcvbuffer))
+ {
+ result = -1;
+ break;
+ }
+ }
+
+ /* Send exit message to server */
+ strcpy (sndbuffer, "#exit");
+ send (clientSocket, sndbuffer, strlen (sndbuffer), 0);
+
+ DBG ("Result = %s\n", (result == 0) ? "Success" : "Fail");
+ close (clientSocket);
+ DBG ("Disconnecting from server.\n");
+ return 0;
+}
diff --git a/app_example/func-test/fork/tcpserver.c b/app_example/func-test/fork/tcpserver.c
new file mode 100644
index 0000000..5474c35
--- /dev/null
+++ b/app_example/func-test/fork/tcpserver.c
@@ -0,0 +1,161 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+
+static struct sockaddr_in g_src;
+int srcPort = 0;
+int destPort = 0;
+int times = 0;
+
+#ifdef DEBUG
+#define DBG(fmt, arg...) do { \
+ DBG(fmt, ##arg); \
+} while(0)
+#else
+#define DBG(fmt, arg...) ((void)0)
+#endif
+
+static void
+setArgsDefault ()
+{
+ memset (&g_src, 0, sizeof (g_src));
+ g_src.sin_family = AF_INET;
+ g_src.sin_addr.s_addr = inet_addr ("0.0.0.0");
+ g_src.sin_port = htons (7895);
+ bzero (&(g_src.sin_zero), 8);
+
+ times = 1;
+}
+
+static int
+process_arg (int argc, char *argv[])
+{
+ int opt = 0;
+ int error = 0;
+ const char *optstring = "s:a:t:";
+
+ if (argc < 5)
+ {
+ DBG
+ ("Param info :-p dest_portid; -d dest_serverIP; -a src_portid; -s src_clientIP; -t times; \n");
+ return -1;
+ }
+ setArgsDefault ();
+ while ((opt = getopt (argc, argv, optstring)) != -1)
+ {
+ switch (opt)
+ {
+ case 's':
+ g_src.sin_addr.s_addr = inet_addr (optarg);
+ break;
+ case 'a':
+ g_src.sin_port = htons (atoi (optarg));
+ break;
+ case 't':
+ times = atoi (optarg);
+ break;
+ }
+ }
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+
+ int sockfd, ret;
+ int newSocket;
+ socklen_t addr_size;
+ static struct sockaddr_in accept_addr;
+ char buffer[1024];
+ pid_t childpid;
+
+ /*
+ * check command line arguments
+ */
+ if (0 != process_arg (argc, argv))
+ {
+ DBG ("Error in argument.%d\n", argc);
+ exit (1);
+ }
+
+ sockfd = socket (AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0)
+ {
+ DBG ("Error in connection.\n");
+ exit (1);
+ }
+ DBG ("Server Socket is created. %d\n", sockfd);
+
+ ret = bind (sockfd, (struct sockaddr *) &g_src, sizeof (g_src));
+ if (ret < 0)
+ {
+ DBG ("Error in binding.\n");
+ exit (1);
+ }
+
+ DBG ("Bind sucess port %d\n", g_src.sin_port);
+
+ if (listen (sockfd, 10) == 0)
+ {
+ DBG ("Listening on %s....\n", inet_ntoa (g_src.sin_addr));
+ }
+ else
+ {
+ DBG ("Error in binding.\n");
+ }
+
+ while (1)
+ {
+ newSocket =
+ accept (sockfd, (struct sockaddr *) &accept_addr, &addr_size);
+ if (newSocket < 0)
+ {
+ DBG ("Error: Exiting here pid %d", getpid ());
+ exit (1);
+ }
+
+ DBG ("Connection accepted from %s:%d fd %d\n",
+ inet_ntoa (accept_addr.sin_addr),
+ ntohs (accept_addr.sin_port), newSocket);
+ if ((childpid = fork ()) == 0)
+ {
+ DBG ("[ PID %d] Child process Created. Pid %d \r\n", getpid (),
+ getpid ());
+ DBG ("[ PID %d] Closing fd %d\n", getpid (), sockfd);
+ close (sockfd);
+
+ while (1)
+ {
+ memset (buffer, '\0', 1024 * sizeof (char));
+ recv (newSocket, buffer, 1024, 0);
+ if (strcmp (buffer, "#exit") == 0)
+ {
+ DBG ("Disconnected from %s:%d\n",
+ inet_ntoa (newAddr.sin_addr),
+ ntohs (newAddr.sin_port));
+ break;
+ }
+ else
+ {
+ DBG ("[PID %d]Client: %s\n", getpid (), buffer);
+ send (newSocket, buffer, strlen (buffer), 0);
+ bzero (buffer, sizeof (buffer));
+ }
+ }
+
+ DBG ("[PID %d]Closing socket %d\r\n", getpid (), newSocket);
+ close (newSocket);
+ }
+
+ }
+
+ DBG ("[PID %d]Process exiting... %d\r\n", getpid (), getpid ());
+ return 0;
+}
diff --git a/src/nSocket/include/nstack_dmm_api.h b/src/nSocket/include/nstack_dmm_api.h
index dff69f3..ab06650 100644
--- a/src/nSocket/include/nstack_dmm_api.h
+++ b/src/nSocket/include/nstack_dmm_api.h
@@ -57,6 +57,7 @@ typedef enum
typedef struct __nstack_extern_ops
{
int (*module_init) (void); /*stack module init */
+ int (*module_init_child) (void); /*stack module init for child process */
int (*fork_init_child) (pid_t p, pid_t c); /*after fork, stack child process init again if needed. */
void (*fork_parent_fd) (int s, pid_t p); /*after fork, stack parent process proc again if needed. */
void (*fork_child_fd) (int s, pid_t p, pid_t c); /*after fork, child record pid for recycle if needed. */
diff --git a/src/nSocket/include/nstack_select.h b/src/nSocket/include/nstack_select.h
index 5c84846..659c477 100644
--- a/src/nSocket/include/nstack_select.h
+++ b/src/nSocket/include/nstack_select.h
@@ -141,6 +141,8 @@ extern i32 select_add_cb (struct select_entry *entry);
extern i32 select_rm_cb (struct select_entry *entry);
extern i32 select_entry_reset (struct select_entry *entry);
extern i32 select_module_init ();
+extern i32 select_module_init_child ();
+
extern struct select_module_info *get_select_module (void);
#ifdef __cplusplus
/* *INDENT-OFF* */
diff --git a/src/nSocket/kernel/linux_kernel_module.c b/src/nSocket/kernel/linux_kernel_module.c
index 6a262d0..eb3dd8d 100644
--- a/src/nSocket/kernel/linux_kernel_module.c
+++ b/src/nSocket/kernel/linux_kernel_module.c
@@ -324,6 +324,7 @@ kernel_stack_register (nstack_proc_cb * ops, nstack_event_cb * val)
ops->extern_ops.ep_ctl = kernel_ep_fd_add;
ops->extern_ops.ep_prewait_proc = kernel_prewait_proc;
ops->extern_ops.module_init = kernel_module_init;
+ ops->extern_ops.module_init_child = kernel_module_init;
ops->extern_ops.stack_alloc_fd = kernel_fd_alloc;
/* don't close file descriptor */
diff --git a/src/nSocket/nstack/event/select/nstack_select.c b/src/nSocket/nstack/event/select/nstack_select.c
index ba64cff..930f1db 100644
--- a/src/nSocket/nstack/event/select/nstack_select.c
+++ b/src/nSocket/nstack/event/select/nstack_select.c
@@ -753,4 +753,26 @@ nssct_set_index (i32 fd, i32 inx)
select_set_index (fd, inx);
}
+i32
+select_module_init_child ()
+{
+ pthread_t select_thread_id;
+ i32 retval;
+
+ if (pthread_create (&select_thread_id, NULL, nstack_select_thread, NULL))
+ {
+ goto ERR_RET;
+ }
+
+ retval = pthread_setname_np (select_thread_id, "nstack_select_child");
+ if (retval)
+ {
+ /*set thread name failed */
+ }
+ return TRUE;
+
+ERR_RET:
+ return FALSE;
+}
+
#endif /* NSTACK_SELECT_MODULE */
diff --git a/src/nSocket/nstack/nstack.c b/src/nSocket/nstack/nstack.c
index 707cb49..861bc37 100644
--- a/src/nSocket/nstack/nstack.c
+++ b/src/nSocket/nstack/nstack.c
@@ -587,7 +587,7 @@ nstack_for_epoll_init ()
NSSOC_LOGINF ("fork]g_nStackInfo.pid=%u,getpid=%d", g_nStackInfo.pid,
getpid ());
- nstack_stack_module_init();
+ nstack_stack_module_init_child();
}
return 0;
}
diff --git a/src/nSocket/nstack/nstack_module.c b/src/nSocket/nstack/nstack_module.c
index bef91e5..9566ab8 100644
--- a/src/nSocket/nstack/nstack_module.c
+++ b/src/nSocket/nstack/nstack_module.c
@@ -265,3 +265,23 @@ nstack_stack_module_init ()
}
return 0;
}
+
+int
+nstack_stack_module_init_child ()
+{
+ ns_uint32 idx;
+ for (idx = 0; idx < g_module_num; idx++)
+ {
+ if (g_nstack_modules.modules[idx].mops.extern_ops.module_init_child)
+ {
+ if (0 !=
+ g_nstack_modules.modules[idx].mops.
+ extern_ops.module_init_child ())
+ {
+ NSSOC_LOGERR ("nstack[%s] modx:%d init child fail",
+ g_nstack_modules.modules[idx].modulename, idx);
+ }
+ }
+ }
+ return 0;
+}
diff --git a/src/nSocket/nstack/nstack_module.h b/src/nSocket/nstack/nstack_module.h
index e0105af..ec81ac1 100644
--- a/src/nSocket/nstack/nstack_module.h
+++ b/src/nSocket/nstack/nstack_module.h
@@ -135,6 +135,7 @@ extern nstack_module_keys g_nstack_module_desc[];
for ((modInx) = 0; ((modInx) < nstack_get_modNum() && (pMod = nstack_get_module((modInx)))); (modInx)++)
int nstack_stack_module_init ();
+int nstack_stack_module_init_child ();
int nstack_get_deploy_type ();
diff --git a/src/nSocket/nstack/nstack_socket.c b/src/nSocket/nstack/nstack_socket.c
index e3da248..cd1557b 100644
--- a/src/nSocket/nstack/nstack_socket.c
+++ b/src/nSocket/nstack/nstack_socket.c
@@ -2775,6 +2775,8 @@ nstack_fork (void)
dmm_spinlock_lock_with_pid (nstack_get_fork_share_lock (),
get_sys_pid ());
nsep_fork_child_proc (parent_pid);
+
+ (void) select_module_init_child ();
common_mem_spinlock_unlock (nstack_get_fork_share_lock ());
}
else if (pid > 0)
diff --git a/stacks/lwip_stack/lwip_src/api/spl_api_msg.c b/stacks/lwip_stack/lwip_src/api/spl_api_msg.c
index 9ba1e92..0986ed4 100644
--- a/stacks/lwip_stack/lwip_src/api/spl_api_msg.c
+++ b/stacks/lwip_stack/lwip_src/api/spl_api_msg.c
@@ -3186,9 +3186,12 @@ update_tcp_state (spl_netconn_t * conn, enum tcp_state state)
spl_state = SPL_CLOSED;
break;
}
- conn->tcp_state = spl_state;
- NSTCP_LOGINF ("conn=%p,private_data=%p,state=%d", conn,
- conn->private_data, spl_state);
+ if (conn->tcp_state != spl_state)
+ {
+ conn->tcp_state = spl_state;
+ NSTCP_LOGINF ("conn=%p,private_data=%p,state=%d", conn,
+ conn->private_data, spl_state);
+ }
}
}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h
index 3b0c9f9..2d35dd0 100644
--- a/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h
+++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h
@@ -431,11 +431,23 @@ ss_set_is_listen_conn (spl_netconn_t * sh, i8 is_listen_conn)
}
static inline i32
+ss_inc_fork_ref (spl_netconn_t * sh)
+{
+ return __sync_add_and_fetch (&sh->recycle.fork_ref, 1);
+}
+
+static inline i32
ss_dec_fork_ref (spl_netconn_t * sh)
{
return __sync_sub_and_fetch (&sh->recycle.fork_ref, 1);
}
+static inline i32
+ss_get_fork_ref (spl_netconn_t * sh)
+{
+ return sh->recycle.fork_ref;
+}
+
static inline int
ss_add_pid (spl_netconn_t * sh, pid_t pid)
{
diff --git a/stacks/lwip_stack/lwip_src/core/spl_timers.c b/stacks/lwip_stack/lwip_src/core/spl_timers.c
index 50582fc..cfa130b 100644
--- a/stacks/lwip_stack/lwip_src/core/spl_timers.c
+++ b/stacks/lwip_stack/lwip_src/core/spl_timers.c
@@ -283,7 +283,6 @@ deal_timeout_sig (void)
int retval;
if (ptimer.first == NULL)
{
- NSPOL_LOGERR ("ptimer.first=NULL!!");
return;
}
tmo = rb_entry (ptimer.first, struct ptimer_node, node);
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c
index 6af2a77..292c17a 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.c
@@ -522,6 +522,34 @@ sbr_com_lock_common (sbr_socket_t * sk)
}
+void
+sbr_com_fork_parent (sbr_socket_t * sk, pid_t p)
+{
+ i32 ref = ss_inc_fork_ref (sbr_get_conn (sk));
+ NSSBR_LOGINF ("inc fork ref] fd=%d, p=%d, ref=%d, conn=%p, private_data=%p",
+ sk->fd, p, ref, sbr_get_conn (sk),
+ sbr_get_conn (sk)->private_data);
+}
+
+void
+sbr_com_fork_child (sbr_socket_t * sk, pid_t p, pid_t c)
+{
+ if (ss_add_pid (sbr_get_conn (sk), c) != 0)
+ {
+ NSSBR_LOGERR
+ ("add pid failed] fd=%d, p=%d, c=%d, ref=%d, conn=%p, private_data=%p",
+ sk->fd, p, c, ss_get_fork_ref (sbr_get_conn (sk)), sbr_get_conn (sk),
+ sbr_get_conn (sk)->private_data);
+ }
+ else
+ {
+ NSSBR_LOGINF
+ ("add pid ok] fd=%d, p=%d, c=%d, ref=%d, conn=%p, private_data=%p",
+ sk->fd, p, c, ss_get_fork_ref (sbr_get_conn (sk)), sbr_get_conn (sk),
+ sbr_get_conn (sk)->private_data);
+ }
+}
+
/*****************************************************************************
* Prototype : sbr_com_unlock_common
* Description : unlock common
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h
index 054393b..1be44cb 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_prot_com.h
@@ -150,6 +150,9 @@ int sbr_get_sockaddr_and_len (u16 port, spl_ip_addr_t * ip_addr,
struct sockaddr *addr, socklen_t * addrlen);
void sbr_com_set_app_info (sbr_socket_t * sk, void *appinfo);
+void sbr_com_fork_parent (sbr_socket_t * sk, pid_t p);
+void sbr_com_fork_child (sbr_socket_t * sk, pid_t p, pid_t c);
+
#ifdef __cplusplus
/* *INDENT-OFF* */
}
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c b/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c
index 94ef483..920d73d 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_protocol_api.c
@@ -44,6 +44,25 @@ sbr_init_protocol ()
}
/*****************************************************************************
+* Prototype : sbr_fork_protocol
+* Description : init protocol
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int
+sbr_fork_protocol ()
+{
+ pid_t pid = updata_sys_pid ();
+
+ NSSBR_LOGINF ("update pid in child]pid=%d", pid);
+ return sbr_fork_stackx ();
+}
+
+/*****************************************************************************
* Prototype : sbr_get_fdopt
* Description : get fdopt by domain type protocol
* Input : int domain
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c
index 331eee1..f3cb5b5 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.c
@@ -172,6 +172,39 @@ sbr_init_stackx ()
}
/*****************************************************************************
+* Prototype : sbr_fork_stackx
+* Description : init stackx res
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int
+sbr_fork_stackx ()
+{
+
+ if (sbr_attach_group_array () != 0)
+ {
+ NSSBR_LOGERR ("sbr_attach_group_array failed");
+ return -1;
+ }
+
+ NSSBR_LOGDBG ("sbr_attach_group_array ok");
+
+ if (sbr_init_tx_pool () != 0)
+ {
+ NSSBR_LOGERR ("init tx pool failed");
+ return -1;
+ }
+
+ NSSBR_LOGDBG ("init tx pool ok");
+ NSSBR_LOGDBG ("sbr_fork_stackx ok");
+ return 0;
+}
+
+/*****************************************************************************
* Prototype : sbr_malloc_conn_for_sk
* Description : malloc netconn for sk,need add pid
* Input : sbr_socket_t* sk
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h
index e139644..73cec7f 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_res_mgr.h
@@ -56,6 +56,7 @@ sbr_get_spl_msg_box (sbr_socket_t * sk, u8 tos)
}
int sbr_init_stackx ();
+int sbr_fork_stackx ();
int sbr_malloc_conn_for_sk (sbr_socket_t * sk, spl_netconn_type_t type);
int sbr_init_conn_for_accept (sbr_socket_t * sk, spl_netconn_t * conn);
void sbr_free_conn_from_sk (sbr_socket_t * sk);
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c b/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c
index c64dc7b..3225c2f 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_tcp.c
@@ -1690,6 +1690,8 @@ sbr_fdopt tcp_fdopt = {
.peak = sbr_com_peak,
.lock_common = sbr_com_lock_common,
.unlock_common = sbr_com_unlock_common,
+ .fork_parent = sbr_com_fork_parent,
+ .fork_child = sbr_com_fork_child,
.ep_getevt = stackx_eventpoll_getEvt,
.ep_ctl = stackx_eventpoll_triggle,
.set_close_stat = NULL,
diff --git a/stacks/lwip_stack/lwip_src/socket/stackx_udp.c b/stacks/lwip_stack/lwip_src/socket/stackx_udp.c
index cf08731..69b822b 100644
--- a/stacks/lwip_stack/lwip_src/socket/stackx_udp.c
+++ b/stacks/lwip_stack/lwip_src/socket/stackx_udp.c
@@ -1163,6 +1163,8 @@ sbr_fdopt udp_fdopt = {
.peak = sbr_com_peak,
.lock_common = sbr_com_lock_common,
.unlock_common = sbr_com_unlock_common,
+ .fork_parent = sbr_com_fork_parent,
+ .fork_child = sbr_com_fork_child,
.ep_getevt = stackx_eventpoll_getEvt,
.ep_ctl = stackx_eventpoll_triggle,
.set_close_stat = NULL,
diff --git a/stacks/lwip_stack/src/sbr/sbr_protocol_api.h b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
index 1c0fb1e..0eac1c4 100644
--- a/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
+++ b/stacks/lwip_stack/src/sbr/sbr_protocol_api.h
@@ -70,6 +70,8 @@ typedef struct
int (*peak) (sbr_socket_t *);
void (*lock_common) (sbr_socket_t *);
void (*unlock_common) (sbr_socket_t *);
+ void (*fork_parent) (sbr_socket_t *, pid_t);
+ void (*fork_child) (sbr_socket_t *, pid_t, pid_t);
unsigned int (*ep_ctl) (sbr_socket_t *, int triggle_ops,
struct epoll_event * event, void *pdata);
unsigned int (*ep_getevt) (sbr_socket_t *, unsigned int events);
@@ -86,7 +88,7 @@ struct sbr_socket_s
};
int sbr_init_protocol ();
-
+int sbr_fork_protocol ();
sbr_fdopt *sbr_get_fdopt (int domain, int type, int protocol);
void sbr_app_touch_in (void); /*app send its version info to nStackMain */
diff --git a/stacks/lwip_stack/src/sbr/sbr_res_mgr.h b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
index 54729d4..e731314 100644
--- a/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
+++ b/stacks/lwip_stack/src/sbr/sbr_res_mgr.h
@@ -117,6 +117,37 @@ sbr_lookup_sk (int fd)
return sk;
}
+/*****************************************************************************
+* Prototype : sbr_free_sk
+* Description : free sock
+* Input : sbr_socket_t * sk
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void
+sbr_free_fd (int fd)
+{
+ if ((fd < 1) || (fd > SBR_MAX_FD_NUM))
+ {
+ NSSBR_LOGERR ("fd is not ok]fd=%d", fd);
+ sbr_set_errno (EBADF);
+ return;
+ }
+
+ sbr_socket_t *sk = &g_res_group.sk[fd];
+ if (!sk->fdopt && !sk->sk_obj && !sk->stack_obj)
+ {
+ NSSBR_LOGERR
+ ("can't free empty fd] fd=%d, fdopt=%p, sk_obj=%p, stack_obj=%p", fd,
+ sk->fdopt, sk->sk_obj, sk->stack_obj);
+ return;
+ }
+ sbr_free_sk (sk);
+}
+
int sbr_init_res ();
#ifdef __cplusplus
diff --git a/stacks/lwip_stack/src/sbr/sbr_socket.c b/stacks/lwip_stack/src/sbr/sbr_socket.c
index 47aefda..e088224 100644
--- a/stacks/lwip_stack/src/sbr/sbr_socket.c
+++ b/stacks/lwip_stack/src/sbr/sbr_socket.c
@@ -1197,6 +1197,45 @@ SBR_INTERCEPT (int, fd_alloc, ())
return sbr_socket (AF_INET, SOCK_STREAM, 0);
}
+SBR_INTERCEPT (int, fork_init_child, (pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG ("fork_init_child() is called]");
+ return sbr_fork_protocol ();
+}
+
+SBR_INTERCEPT (void, fork_parent_fd, (int s, pid_t p))
+{
+ NSSBR_LOGDBG ("fork_parent_fd() is called]");
+ sbr_socket_t *sk = sbr_lookup_sk (s);
+
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->fork_parent (sk, p);
+}
+
+SBR_INTERCEPT (void, fork_child_fd, (int s, pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG ("fork_child_fd() is called]");
+ sbr_socket_t *sk = sbr_lookup_sk (s);
+
+ if (!sk)
+ {
+ return;
+ }
+
+ sk->fdopt->fork_child (sk, p, c);
+
+}
+
+SBR_INTERCEPT (void, fork_free_fd, (int s, pid_t p, pid_t c))
+{
+ NSSBR_LOGDBG ("fork_free_fd() is called]");
+ sbr_free_fd (s);
+}
+
/*****************************************************************************
* Prototype : nstack_stack_register
* Description : reg api to nsocket
@@ -1227,5 +1266,9 @@ nstack_stack_register (nstack_proc_cb * ops, nstack_event_cb * val)
(ops->extern_ops).ep_ctl = GET_SBR_INTERCEPT (ep_ctl);
(ops->extern_ops).peak = GET_SBR_INTERCEPT (peak);
(ops->extern_ops).stack_alloc_fd = GET_SBR_INTERCEPT (fd_alloc); /*alloc a fd id for epoll */
+ (ops->extern_ops).fork_init_child = GET_SBR_INTERCEPT (fork_init_child);
+ (ops->extern_ops).fork_parent_fd = GET_SBR_INTERCEPT (fork_parent_fd);
+ (ops->extern_ops).fork_child_fd = GET_SBR_INTERCEPT (fork_child_fd);
+ (ops->extern_ops).fork_free_fd = GET_SBR_INTERCEPT (fork_free_fd);
return 0;
}