add-enable-nofork-config-option.patch

Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
Andy Green 2011-01-20 10:23:50 +00:00
parent e92cd1764e
commit ed11a02201
6 changed files with 219 additions and 111 deletions

View file

@ -15,6 +15,9 @@ $ libwebsockets-test-server
should be enough to get a test server listening on port 7861.
Testing
-------
If you point your browser (eg, Chrome) to
http://127.0.0.1:7681
@ -23,6 +26,9 @@ It will fetch a script in the form of test.html, and then run the
script in there on the browser to open a websocket connection.
Incrementing numbers should appear in the browser display.
Using SSL
---------
To test it using SSL/WSS, just run the test server with
$ libwebsockets-test-server --ssl
@ -41,5 +47,23 @@ same.
test-server.c is all that is needed to use libwebsockets for
serving both the script html over http and websockets.
2010-11-08 Andy Green <andy@warmcat.com>
Forkless operation
------------------
If your target device does not offer fork(), you can use
libwebsockets from your own main loop instead. Use the
configure option --nofork and simply call libwebsocket_service()
from your own main loop as shown in the test app sources.
Websocket version supported
---------------------------
Right now this is tested and working on websockets protocol 76/00
Untested code is in for 04 support, there is no browser support
available yet to test it with. Libwebsockets should autoselect
between the supported versions according to what the browser
asks for.
2011-01-20 Andy Green <andy@warmcat.com>

175
configure vendored
View file

@ -735,6 +735,7 @@ with_gnu_ld
with_sysroot
enable_libtool_lock
enable_openssl
enable_nofork
'
ac_precious_vars='build_alias
host_alias
@ -1378,6 +1379,7 @@ Optional Features:
--enable-dependency-tracking do not reject slow dependency extractors
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-openssl Enables https support and needs openssl libs
--enable-nofork Disables fork-related options
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -1739,6 +1741,60 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_func
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
# variable VAR accordingly.
ac_fn_c_check_type ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
if (sizeof ($2))
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
if (sizeof (($2)))
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
eval "$3=yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_type
# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
@ -1829,60 +1885,6 @@ fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_mongrel
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
# variable VAR accordingly.
ac_fn_c_check_type ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
if (sizeof ($2))
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
if (sizeof (($2)))
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
eval "$3=yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_type
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
@ -12014,37 +12016,16 @@ fi
CFLAGS="$CFLAGS -DLWS_OPENSSL_SUPPORT"
fi
# Checks for header files.
for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
# Check whether --enable-nofork was given.
if test "${enable_nofork+set}" = set; then :
enableval=$enable_nofork; nofork=yes
fi
done
# Checks for typedefs, structures, and compiler characteristics.
ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
if test "x$ac_cv_type_size_t" = xyes; then :
if test "x$nofork" = "xyes" ; then
CFLAGS="$CFLAGS -DLWS_NO_FORK"
else
cat >>confdefs.h <<_ACEOF
#define size_t unsigned int
_ACEOF
fi
# Checks for library functions.
ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
if test "x$ac_cv_type_pid_t" = xyes; then :
@ -12269,6 +12250,40 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi
fi
# Checks for header files.
for ac_header in fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
# Checks for typedefs, structures, and compiler characteristics.
ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
if test "x$ac_cv_type_size_t" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define size_t unsigned int
_ACEOF
fi
# Checks for library functions.
for ac_header in stdlib.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"

View file

@ -28,6 +28,17 @@ AC_CHECK_LIB([ssl], [SSL_library_init])
CFLAGS="$CFLAGS -DLWS_OPENSSL_SUPPORT"
fi
AC_ARG_ENABLE(nofork,
[ --enable-nofork Disables fork-related options],
[ nofork=yes
])
if test "x$nofork" = "xyes" ; then
CFLAGS="$CFLAGS -DLWS_NO_FORK"
else
AC_FUNC_FORK
fi
# Checks for header files.
@ -37,7 +48,7 @@ AC_CHECK_HEADERS([fcntl.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h])
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([bzero memset socket strerror])

View file

@ -617,6 +617,8 @@ libwebsocket_create_server(int port,
return this;
}
#ifndef LWS_NO_FORK
/**
* libwebsockets_fork_service_loop() - Optional helper function forks off
* a process for the websocket server loop.
@ -635,29 +637,38 @@ libwebsockets_fork_service_loop(struct libwebsocket_context *this)
struct sockaddr_in cli_addr;
int n;
if (fork())
n = fork();
if (n < 0)
return n;
if (!n) {
/* main process context */
for (client = 1; client < this->count_protocols + 1; client++) {
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "Unable to create socket\n");
return -1;
}
cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(
this->protocols[client - 1].broadcast_socket_port);
cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
n = connect(fd, (struct sockaddr *)&cli_addr,
sizeof cli_addr);
if (n < 0) {
fprintf(stderr, "Unable to connect to "
"broadcast socket %d, %s\n",
client, strerror(errno));
return -1;
}
this->protocols[client - 1].broadcast_socket_user_fd = fd;
}
return 0;
for (client = 1; client < this->count_protocols + 1; client++) {
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "Unable to create socket\n");
return -1;
}
cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(
this->protocols[client - 1].broadcast_socket_port);
cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
n = connect(fd, (struct sockaddr *)&cli_addr,
sizeof cli_addr);
if (n < 0) {
fprintf(stderr, "Unable to connect to "
"broadcast socket %d, %s\n",
client, strerror(errno));
return -1;
}
this->protocols[client - 1].broadcast_socket_user_fd = fd;
}
/* we want a SIGHUP when our parent goes down */
@ -672,6 +683,8 @@ libwebsockets_fork_service_loop(struct libwebsocket_context *this)
return 0;
}
#endif
/**
* libwebsockets_get_protocol() - Returns a protocol pointer from a websocket
* connection.

View file

@ -32,7 +32,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#ifndef LWS_NO_FORK
#include <sys/prctl.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>

View file

@ -264,12 +264,15 @@ int main(int argc, char **argv)
return -1;
}
buf[LWS_SEND_BUFFER_PRE_PADDING] = 'x';
#ifdef LWS_NO_FORK
/*
* After initializing and creating the websocket server in its own fork
* we return to the main process here
* This example shows how to work with no forked service loop
*/
buf[LWS_SEND_BUFFER_PRE_PADDING] = 'x';
fprintf(stderr, " Using no-fork service loop\n");
while (1) {
@ -297,14 +300,54 @@ int main(int argc, char **argv)
* we have to give the websockets an opportunity to service
* "manually".
*
* There's an optional call libwebsockets_fork_service_loop()
* we could have used before this while loop, then the
* websockets would have been serviced in a forked process
* and we would not have to do the call below inside our loop.
* If no socket is needing service, the call below returns
* immediately and quickly.
*/
libwebsocket_service(server, 0);
}
#else
/*
* This example shows how to work with the forked websocket service loop
*/
fprintf(stderr, " Using forked service loop\n");
/*
* This forks the websocket service action into a subprocess so we
* don't have to take care about it.
*/
n = libwebsockets_fork_service_loop(server);
if (n < 0) {
fprintf(stderr, "Unable to fork service loop %d\n", n);
return 1;
}
while (1) {
usleep(50000);
/*
* This broadcasts to all dumb-increment-protocol connections
* at 20Hz.
*
* We're just sending a character 'x', in these examples the
* callbacks send their own per-connection content.
*
* You have to send something with nonzero length to get the
* callback actions delivered.
*
* We take care of pre-and-post padding allocation.
*/
libwebsockets_broadcast(&protocols[PROTOCOL_DUMB_INCREMENT],
&buf[LWS_SEND_BUFFER_PRE_PADDING], 1);
}
#endif
return 0;
}