Skip to content

Commit

Permalink
Merge pull request #163 from malloch/optimize-server2
Browse files Browse the repository at this point in the history
Optimize server2
  • Loading branch information
radarsat1 authored Nov 27, 2024
2 parents d109a24 + 68b49ad commit a3dc0cb
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 271 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,13 @@ sockets. IPv6 is currently disabled by default, but you can enable it
using

./configure --enable-ipv6

## Poll() vs Select()

Some platforms may have both `poll()` and `select()` available for listening efficiently on multiple servers/sockets. In this case, liblo will default to using `poll` since it is comsidered to be more scalable. However, on some platforms (e.g. MacOS) the liblo code path using `select()` is considerably faster so you may wish to explictly disable support for `poll` if your applications do not require extreme scalability and are sensitive to small differences in efficiency. This can be done when compiling the library from source, either using configure:

./configure --disable-poll

or if using cmake:

cmake -DWITH_POLL=OFF <path>
8 changes: 7 additions & 1 deletion cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ option(WITH_EXAMPLES "Enable building examples." ON)
option(WITH_CPP_TESTS "Enable building C++ wrapper tests." ON)
option(WITH_STATIC "Enable building static library." OFF)
option(THREADING "Build with threading support." ON)
option(WITH_POLL "Build with poll support." ON)

if (WITH_STATIC)
message(STATUS "If you are using the static library build, please keep in mind (and inform yourself of the implications) that liblo is licensed with LGPL v2.1+.")
Expand Down Expand Up @@ -141,7 +142,12 @@ set(EXAMPLE_SERVER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../examples/example_serve
set(EXAMPLE_TCP_ECHO_SERVER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../examples/example_tcp_echo_server.c)
set(NONBLOCKING_SERVER_EXAMPLE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../examples/nonblocking_server_example.c)

check_symbol_exists(poll poll.h HAVE_POLL)
if (WITH_POLL)
check_symbol_exists(poll poll.h HAVE_POLL)
else()
message(STATUS "Excluding poll support.")
set(HAVE_POLL OFF)
endif()
check_symbol_exists(select sys/select.h HAVE_SELECT)
if(NOT HAVE_POLL AND NOT HAVE_SELECT)
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
Expand Down
12 changes: 11 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ AC_CHECK_FUNC([select], [AC_DEFINE(HAVE_SELECT, [1], [Define to 1 if select() is
AC_DEFINE(HAVE_SELECT, [1], [Define to 1 if select() is available.])
is_windows=yes],[AC_MSG_RESULT(no)])
])
AC_CHECK_FUNC([poll], [AC_DEFINE(HAVE_POLL, [1], [Define to 1 if poll() is available.])])
AC_CHECK_FUNC([setvbuf], [AC_DEFINE(HAVE_SETVBUF, [1], [Define to 1 if setvbuf() is available.])])

AM_CONDITIONAL(WINDOWS, test x$is_windows = xyes)
Expand Down Expand Up @@ -260,6 +259,17 @@ AM_CONDITIONAL([COMPILE_TOOLS],[test x$enable_tools != xno])
AM_CONDITIONAL([COMPILE_EXAMPLES],[test x$enable_examples != xno])
AM_CONDITIONAL([ENABLE_NETWORK_TESTS],[test x$enable_network_tests != xno])

# Check if poll is wanted
AC_ARG_ENABLE(poll,
[ --disable-poll Disable compiling with poll support],
[want_poll=$enableval],
[want_poll=yes])

# Check for whether poll is wanted, and if so, did we find it.
if test "x$want_poll" = "xyes"; then
AC_CHECK_FUNC([poll], [AC_DEFINE(HAVE_POLL, [1], [Define to 1 if poll() is available.])])
fi

if ! test x$enable_network_tests = xno; then
AC_DEFINE(ENABLE_NETWORK_TESTS, [1],
[Define this to enable network tests.])
Expand Down
8 changes: 5 additions & 3 deletions lo/lo_lowlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,9 @@ void lo_server_free(lo_server s);
* \param timeout A timeout in milliseconds to wait for the incoming packet.
* a value of 0 will return immediately.
*
* The return value is 1 if there is a message waiting or 0 if
* there is no message. If there is a message waiting you can now
* The return value is 1 if there is a message waiting, 0 if
* there is no message, and -1 if there is an error that causes the
* function to return early. If there is a message waiting you can now
* call lo_server_recv() to receive that message.
*/
int lo_server_wait(lo_server s, int timeout);
Expand All @@ -815,7 +816,8 @@ int lo_server_wait(lo_server s, int timeout);
* a value of 0 will return immediately.
*
* The return value is the number of servers with a message waiting or
* 0 if there is no message. If there is a message waiting you can now
* -1 if there is an error that causes the function to return early.
* If there is a message waiting you can now
* call lo_server_recv() to receive that message.
*/
int lo_servers_wait(lo_server *s, int *status, int num_servers, int timeout);
Expand Down
3 changes: 2 additions & 1 deletion src/lo_types_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ struct socket_context {
#ifdef HAVE_POLL
typedef struct pollfd lo_server_fd_type;
#else
typedef struct { int fd; } lo_server_fd_type;
typedef struct { int fd; int revents; } lo_server_fd_type;
#define POLLIN 0x001
#endif

typedef struct _lo_server {
Expand Down
Loading

0 comments on commit a3dc0cb

Please sign in to comment.