libevent/test/regress_listener.c

618 lines
17 KiB
C
Raw Permalink Normal View History

/*
2012-02-10 17:29:53 -05:00
* Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "util-internal.h"
#ifdef _WIN32
#ifdef EVENT__HAVE_AFUNIX_H
#include <afunix.h>
#endif
#include <io.h>
#include <winsock2.h>
#include <windows.h>
#include <winerror.h>
#endif
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
2011-02-13 01:22:25 -05:00
# ifdef _XOPEN_SOURCE_EXTENDED
# include <arpa/inet.h>
# endif
#ifdef EVENT__HAVE_SYS_UN_H
#include <sys/un.h>
#endif
#include <unistd.h>
#endif
#ifdef EVENT__HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "event2/listener.h"
#include "event2/event.h"
#include "event2/util.h"
Fix deadlock in case of evconnlistener_disable() in parallel with callback I've got an issue when stop evconnlistener not in the event_base_loop() thread. evconnlistener_disable() acquired lev->lock, if the same time, user callbacks is runing, the event thread released lock, after callback finished, it try to aquire the lock again, I think this makes conflict: Here is backtraces: thread 1: 0 __lll_lock_wait (futex=futex@entry=0x555555559a60, private=0) at lowlevellock.c:52 1 0x00007ffff7f2a131 in __GI___pthread_mutex_lock (mutex=0x555555559a60) at ../nptl/pthread_mutex_lock.c:115 2 0x00007ffff7f424c9 in evthread_posix_lock (mode=0, lock_=0x555555559a60) at evthread_pthread.c:79 3 0x00007ffff7f7dc12 in listener_read_cb (fd=7, what=2, p=0x5555555599a0) at listener.c:439 4 0x00007ffff7f6d758 in event_persist_closure (base=0x555555559370, ev=0x5555555599d8) at event.c:1645 5 0x00007ffff7f6da60 in event_process_active_single_queue (base=0x555555559370, activeq=0x5555555597e0, max_to_process=2147483647, endtime=0x0) at event.c:1704 6 0x00007ffff7f6e018 in event_process_active (base=0x555555559370) at event.c:1805 7 0x00007ffff7f6e92a in event_base_loop (base=0x555555559370, flags=0) at event.c:2047 8 0x0000555555555449 in main () at test_listen.c:67 thread 2: 0 futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x555555559858) at ../sysdeps/nptl/futex-internal.h:183 1 __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555555559800, cond=0x555555559830) at pthread_cond_wait.c:508 2 __pthread_cond_wait (cond=0x555555559830, mutex=0x555555559800) at pthread_cond_wait.c:638 3 0x00007ffff7f426f3 in evthread_posix_cond_wait (cond_=0x555555559830, lock_=0x555555559800, tv=0x0) at evthread_pthread.c:162 4 0x00007ffff7f70bc5 in event_del_nolock_ (ev=0x5555555599d8, blocking=2) at event.c:2934 5 0x00007ffff7f70748 in event_del_ (ev=0x5555555599d8, blocking=2) at event.c:2821 6 0x00007ffff7f707a1 in event_del (ev=0x5555555599d8) at event.c:2830 7 0x00007ffff7f7d76e in event_listener_disable (lev=0x5555555599a0) at listener.c:343 8 0x00007ffff7f7d6e5 in evconnlistener_disable (lev=0x5555555599a0) at listener.c:325 9 0x00005555555552c3 in disable_thread (arg=0x5555555599a0) at test_listen.c:27 10 0x00007ffff7f27609 in start_thread (arg=<optimized out>) at pthread_create.c:477 11 0x00007ffff7e4e293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
2021-11-17 08:40:40 +08:00
#ifndef EVENT__DISABLE_THREAD_SUPPORT
#include "event2/thread.h"
#include "regress_thread.h"
#endif
#include "strlcpy-internal.h"
#include "regress.h"
#include "tinytest.h"
#include "tinytest_macros.h"
#ifdef _WIN32
#define unlink _unlink
#define close _close
#endif
static void
acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *addr, int socklen, void *arg)
{
int *ptr = arg;
--*ptr;
TT_BLATHER(("Got one for %p", ptr));
evutil_closesocket(fd);
if (! *ptr)
evconnlistener_disable(listener);
}
static void
regress_pick_a_port(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener1 = NULL, *listener2 = NULL;
struct sockaddr_in sin;
int count1 = 2, count2 = 1;
struct sockaddr_storage ss1, ss2;
struct sockaddr_in *sin1, *sin2;
ev_socklen_t slen1 = sizeof(ss1), slen2 = sizeof(ss2);
unsigned int flags =
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC;
evutil_socket_t fd1, fd2, fd3;
fd1 = fd2 = fd3 = EVUTIL_INVALID_SOCKET;
if (data->setup_data && strstr((char*)data->setup_data, "ts")) {
flags |= LEV_OPT_THREADSAFE;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = 0; /* "You pick!" */
listener1 = evconnlistener_new_bind(base, acceptcb, &count1,
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
tt_assert(listener1);
listener2 = evconnlistener_new_bind(base, acceptcb, &count2,
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
tt_assert(listener2);
tt_assert(evconnlistener_get_fd(listener1) != EVUTIL_INVALID_SOCKET);
tt_assert(evconnlistener_get_fd(listener2) != EVUTIL_INVALID_SOCKET);
tt_assert(getsockname(evconnlistener_get_fd(listener1),
(struct sockaddr*)&ss1, &slen1) == 0);
tt_assert(getsockname(evconnlistener_get_fd(listener2),
(struct sockaddr*)&ss2, &slen2) == 0);
tt_int_op(ss1.ss_family, ==, AF_INET);
tt_int_op(ss2.ss_family, ==, AF_INET);
sin1 = (struct sockaddr_in*)&ss1;
sin2 = (struct sockaddr_in*)&ss2;
tt_int_op(ntohl(sin1->sin_addr.s_addr), ==, 0x7f000001);
tt_int_op(ntohl(sin2->sin_addr.s_addr), ==, 0x7f000001);
tt_int_op(sin1->sin_port, !=, sin2->sin_port);
tt_ptr_op(evconnlistener_get_base(listener1), ==, base);
tt_ptr_op(evconnlistener_get_base(listener2), ==, base);
fd1 = fd2 = fd3 = EVUTIL_INVALID_SOCKET;
Have all visible internal function names end with an underscore. We haven't had a convention for naming internal functions in -internal.h versus naming visible functions in include/**.h. This patch changes every function declared in a -internal.h file to be named ending with an underscore. Static function names are unaffected, since there's no risk of calling them from outside Libevent. This is an automatic conversion. The script that produced was made by running the following script over the output of ctags --c-kinds=pf -o - *-internal.h | cut -f 1 | sort| uniq (GNU ctags was required.) ===== #!/usr/bin/perl -w -n use strict; BEGIN { print "#!/usr/bin/perl -w -i -p\n\n"; } chomp; my $ident = $_; next if ($ident =~ /_$/); next if ($ident =~ /^TAILQ/); my $better = "${ident}_"; print "s/(?<![A-Za-z0-9_])$ident(?![A-Za-z0-9_])/$better/g;\n"; === And then running the script below that it generated over all === the .c and .h files again #!/usr/bin/perl -w -i -p s/(?<![A-Za-z0-9_])bufferevent_async_can_connect(?![A-Za-z0-9_])/bufferevent_async_can_connect_/g; s/(?<![A-Za-z0-9_])bufferevent_async_connect(?![A-Za-z0-9_])/bufferevent_async_connect_/g; s/(?<![A-Za-z0-9_])bufferevent_async_new(?![A-Za-z0-9_])/bufferevent_async_new_/g; s/(?<![A-Za-z0-9_])bufferevent_async_set_connected(?![A-Za-z0-9_])/bufferevent_async_set_connected_/g; s/(?<![A-Za-z0-9_])bufferevent_decref(?![A-Za-z0-9_])/bufferevent_decref_/g; s/(?<![A-Za-z0-9_])bufferevent_disable_hard(?![A-Za-z0-9_])/bufferevent_disable_hard_/g; s/(?<![A-Za-z0-9_])bufferevent_enable_locking(?![A-Za-z0-9_])/bufferevent_enable_locking_/g; s/(?<![A-Za-z0-9_])bufferevent_incref(?![A-Za-z0-9_])/bufferevent_incref_/g; s/(?<![A-Za-z0-9_])bufferevent_init_common(?![A-Za-z0-9_])/bufferevent_init_common_/g; s/(?<![A-Za-z0-9_])bufferevent_remove_from_rate_limit_group_internal(?![A-Za-z0-9_])/bufferevent_remove_from_rate_limit_group_internal_/g; s/(?<![A-Za-z0-9_])bufferevent_suspend_read(?![A-Za-z0-9_])/bufferevent_suspend_read_/g; s/(?<![A-Za-z0-9_])bufferevent_suspend_write(?![A-Za-z0-9_])/bufferevent_suspend_write_/g; s/(?<![A-Za-z0-9_])bufferevent_unsuspend_read(?![A-Za-z0-9_])/bufferevent_unsuspend_read_/g; s/(?<![A-Za-z0-9_])bufferevent_unsuspend_write(?![A-Za-z0-9_])/bufferevent_unsuspend_write_/g; s/(?<![A-Za-z0-9_])evbuffer_commit_read(?![A-Za-z0-9_])/evbuffer_commit_read_/g; s/(?<![A-Za-z0-9_])evbuffer_commit_write(?![A-Za-z0-9_])/evbuffer_commit_write_/g; s/(?<![A-Za-z0-9_])evbuffer_invoke_callbacks(?![A-Za-z0-9_])/evbuffer_invoke_callbacks_/g; s/(?<![A-Za-z0-9_])evbuffer_launch_read(?![A-Za-z0-9_])/evbuffer_launch_read_/g; s/(?<![A-Za-z0-9_])evbuffer_launch_write(?![A-Za-z0-9_])/evbuffer_launch_write_/g; s/(?<![A-Za-z0-9_])evbuffer_overlapped_new(?![A-Za-z0-9_])/evbuffer_overlapped_new_/g; s/(?<![A-Za-z0-9_])evbuffer_set_parent(?![A-Za-z0-9_])/evbuffer_set_parent_/g; s/(?<![A-Za-z0-9_])event_active_nolock(?![A-Za-z0-9_])/event_active_nolock_/g; s/(?<![A-Za-z0-9_])event_base_add_virtual(?![A-Za-z0-9_])/event_base_add_virtual_/g; s/(?<![A-Za-z0-9_])event_base_assert_ok(?![A-Za-z0-9_])/event_base_assert_ok_/g; s/(?<![A-Za-z0-9_])event_base_del_virtual(?![A-Za-z0-9_])/event_base_del_virtual_/g; s/(?<![A-Za-z0-9_])event_base_get_deferred_cb_queue(?![A-Za-z0-9_])/event_base_get_deferred_cb_queue_/g; s/(?<![A-Za-z0-9_])event_base_get_iocp(?![A-Za-z0-9_])/event_base_get_iocp_/g; s/(?<![A-Za-z0-9_])event_base_start_iocp(?![A-Za-z0-9_])/event_base_start_iocp_/g; s/(?<![A-Za-z0-9_])event_base_stop_iocp(?![A-Za-z0-9_])/event_base_stop_iocp_/g; s/(?<![A-Za-z0-9_])event_changelist_add(?![A-Za-z0-9_])/event_changelist_add_/g; s/(?<![A-Za-z0-9_])event_changelist_del(?![A-Za-z0-9_])/event_changelist_del_/g; s/(?<![A-Za-z0-9_])event_changelist_freemem(?![A-Za-z0-9_])/event_changelist_freemem_/g; s/(?<![A-Za-z0-9_])event_changelist_init(?![A-Za-z0-9_])/event_changelist_init_/g; s/(?<![A-Za-z0-9_])event_changelist_remove_all(?![A-Za-z0-9_])/event_changelist_remove_all_/g; s/(?<![A-Za-z0-9_])event_deferred_cb_cancel(?![A-Za-z0-9_])/event_deferred_cb_cancel_/g; s/(?<![A-Za-z0-9_])event_deferred_cb_init(?![A-Za-z0-9_])/event_deferred_cb_init_/g; s/(?<![A-Za-z0-9_])event_deferred_cb_queue_init(?![A-Za-z0-9_])/event_deferred_cb_queue_init_/g; s/(?<![A-Za-z0-9_])event_deferred_cb_schedule(?![A-Za-z0-9_])/event_deferred_cb_schedule_/g; s/(?<![A-Za-z0-9_])event_get_win32_extension_fns(?![A-Za-z0-9_])/event_get_win32_extension_fns_/g; s/(?<![A-Za-z0-9_])event_iocp_activate_overlapped(?![A-Za-z0-9_])/event_iocp_activate_overlapped_/g; s/(?<![A-Za-z0-9_])event_iocp_port_associate(?![A-Za-z0-9_])/event_iocp_port_associate_/g; s/(?<![A-Za-z0-9_])event_iocp_port_launch(?![A-Za-z0-9_])/event_iocp_port_launch_/g; s/(?<![A-Za-z0-9_])event_iocp_shutdown(?![A-Za-z0-9_])/event_iocp_shutdown_/g; s/(?<![A-Za-z0-9_])event_overlapped_init(?![A-Za-z0-9_])/event_overlapped_init_/g; s/(?<![A-Za-z0-9_])evhttp_connection_connect(?![A-Za-z0-9_])/evhttp_connection_connect_/g; s/(?<![A-Za-z0-9_])evhttp_connection_fail(?![A-Za-z0-9_])/evhttp_connection_fail_/g; s/(?<![A-Za-z0-9_])evhttp_connection_reset(?![A-Za-z0-9_])/evhttp_connection_reset_/g; s/(?<![A-Za-z0-9_])evhttp_parse_firstline(?![A-Za-z0-9_])/evhttp_parse_firstline_/g; s/(?<![A-Za-z0-9_])evhttp_parse_headers(?![A-Za-z0-9_])/evhttp_parse_headers_/g; s/(?<![A-Za-z0-9_])evhttp_response_code(?![A-Za-z0-9_])/evhttp_response_code_/g; s/(?<![A-Za-z0-9_])evhttp_send_page(?![A-Za-z0-9_])/evhttp_send_page_/g; s/(?<![A-Za-z0-9_])evhttp_start_read(?![A-Za-z0-9_])/evhttp_start_read_/g; s/(?<![A-Za-z0-9_])EVLOCK_TRY_LOCK(?![A-Za-z0-9_])/EVLOCK_TRY_LOCK_/g; s/(?<![A-Za-z0-9_])evmap_check_integrity(?![A-Za-z0-9_])/evmap_check_integrity_/g; s/(?<![A-Za-z0-9_])evmap_delete_all(?![A-Za-z0-9_])/evmap_delete_all_/g; s/(?<![A-Za-z0-9_])evmap_foreach_event(?![A-Za-z0-9_])/evmap_foreach_event_/g; s/(?<![A-Za-z0-9_])evmap_io_active(?![A-Za-z0-9_])/evmap_io_active_/g; s/(?<![A-Za-z0-9_])evmap_io_add(?![A-Za-z0-9_])/evmap_io_add_/g; s/(?<![A-Za-z0-9_])evmap_io_clear(?![A-Za-z0-9_])/evmap_io_clear_/g; s/(?<![A-Za-z0-9_])evmap_io_del(?![A-Za-z0-9_])/evmap_io_del_/g; s/(?<![A-Za-z0-9_])evmap_io_get_fdinfo(?![A-Za-z0-9_])/evmap_io_get_fdinfo_/g; s/(?<![A-Za-z0-9_])evmap_io_initmap(?![A-Za-z0-9_])/evmap_io_initmap_/g; s/(?<![A-Za-z0-9_])evmap_reinit(?![A-Za-z0-9_])/evmap_reinit_/g; s/(?<![A-Za-z0-9_])evmap_signal_active(?![A-Za-z0-9_])/evmap_signal_active_/g; s/(?<![A-Za-z0-9_])evmap_signal_add(?![A-Za-z0-9_])/evmap_signal_add_/g; s/(?<![A-Za-z0-9_])evmap_signal_clear(?![A-Za-z0-9_])/evmap_signal_clear_/g; s/(?<![A-Za-z0-9_])evmap_signal_del(?![A-Za-z0-9_])/evmap_signal_del_/g; s/(?<![A-Za-z0-9_])evmap_signal_initmap(?![A-Za-z0-9_])/evmap_signal_initmap_/g; s/(?<![A-Za-z0-9_])evrpc_hook_associate_meta(?![A-Za-z0-9_])/evrpc_hook_associate_meta_/g; s/(?<![A-Za-z0-9_])evrpc_hook_context_free(?![A-Za-z0-9_])/evrpc_hook_context_free_/g; s/(?<![A-Za-z0-9_])evrpc_hook_meta_new(?![A-Za-z0-9_])/evrpc_hook_meta_new_/g; s/(?<![A-Za-z0-9_])evrpc_reqstate_free(?![A-Za-z0-9_])/evrpc_reqstate_free_/g; s/(?<![A-Za-z0-9_])evsig_dealloc(?![A-Za-z0-9_])/evsig_dealloc_/g; s/(?<![A-Za-z0-9_])evsig_init(?![A-Za-z0-9_])/evsig_init_/g; s/(?<![A-Za-z0-9_])evsig_set_base(?![A-Za-z0-9_])/evsig_set_base_/g; s/(?<![A-Za-z0-9_])ev_token_bucket_get_tick(?![A-Za-z0-9_])/ev_token_bucket_get_tick_/g; s/(?<![A-Za-z0-9_])ev_token_bucket_init(?![A-Za-z0-9_])/ev_token_bucket_init_/g; s/(?<![A-Za-z0-9_])ev_token_bucket_update(?![A-Za-z0-9_])/ev_token_bucket_update_/g; s/(?<![A-Za-z0-9_])evutil_accept4(?![A-Za-z0-9_])/evutil_accept4_/g; s/(?<![A-Za-z0-9_])evutil_addrinfo_append(?![A-Za-z0-9_])/evutil_addrinfo_append_/g; s/(?<![A-Za-z0-9_])evutil_adjust_hints_for_addrconfig(?![A-Za-z0-9_])/evutil_adjust_hints_for_addrconfig_/g; s/(?<![A-Za-z0-9_])evutil_ersatz_socketpair(?![A-Za-z0-9_])/evutil_ersatz_socketpair_/g; s/(?<![A-Za-z0-9_])evutil_eventfd(?![A-Za-z0-9_])/evutil_eventfd_/g; s/(?<![A-Za-z0-9_])evutil_format_sockaddr_port(?![A-Za-z0-9_])/evutil_format_sockaddr_port_/g; s/(?<![A-Za-z0-9_])evutil_getaddrinfo_async(?![A-Za-z0-9_])/evutil_getaddrinfo_async_/g; s/(?<![A-Za-z0-9_])evutil_getaddrinfo_common(?![A-Za-z0-9_])/evutil_getaddrinfo_common_/g; s/(?<![A-Za-z0-9_])evutil_getenv(?![A-Za-z0-9_])/evutil_getenv_/g; s/(?<![A-Za-z0-9_])evutil_hex_char_to_int(?![A-Za-z0-9_])/evutil_hex_char_to_int_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISALNUM(?![A-Za-z0-9_])/EVUTIL_ISALNUM_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISALPHA(?![A-Za-z0-9_])/EVUTIL_ISALPHA_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISDIGIT(?![A-Za-z0-9_])/EVUTIL_ISDIGIT_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISLOWER(?![A-Za-z0-9_])/EVUTIL_ISLOWER_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISPRINT(?![A-Za-z0-9_])/EVUTIL_ISPRINT_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISSPACE(?![A-Za-z0-9_])/EVUTIL_ISSPACE_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISUPPER(?![A-Za-z0-9_])/EVUTIL_ISUPPER_/g; s/(?<![A-Za-z0-9_])EVUTIL_ISXDIGIT(?![A-Za-z0-9_])/EVUTIL_ISXDIGIT_/g; s/(?<![A-Za-z0-9_])evutil_load_windows_system_library(?![A-Za-z0-9_])/evutil_load_windows_system_library_/g; s/(?<![A-Za-z0-9_])evutil_make_internal_pipe(?![A-Za-z0-9_])/evutil_make_internal_pipe_/g; s/(?<![A-Za-z0-9_])evutil_new_addrinfo(?![A-Za-z0-9_])/evutil_new_addrinfo_/g; s/(?<![A-Za-z0-9_])evutil_open_closeonexec(?![A-Za-z0-9_])/evutil_open_closeonexec_/g; s/(?<![A-Za-z0-9_])evutil_read_file(?![A-Za-z0-9_])/evutil_read_file_/g; s/(?<![A-Za-z0-9_])evutil_resolve(?![A-Za-z0-9_])/evutil_resolve_/g; s/(?<![A-Za-z0-9_])evutil_set_evdns_getaddrinfo_fn(?![A-Za-z0-9_])/evutil_set_evdns_getaddrinfo_fn_/g; s/(?<![A-Za-z0-9_])evutil_sockaddr_is_loopback(?![A-Za-z0-9_])/evutil_sockaddr_is_loopback_/g; s/(?<![A-Za-z0-9_])evutil_socket(?![A-Za-z0-9_])/evutil_socket_/g; s/(?<![A-Za-z0-9_])evutil_socket_connect(?![A-Za-z0-9_])/evutil_socket_connect_/g; s/(?<![A-Za-z0-9_])evutil_socket_finished_connecting(?![A-Za-z0-9_])/evutil_socket_finished_connecting_/g; s/(?<![A-Za-z0-9_])EVUTIL_TOLOWER(?![A-Za-z0-9_])/EVUTIL_TOLOWER_/g; s/(?<![A-Za-z0-9_])EVUTIL_TOUPPER(?![A-Za-z0-9_])/EVUTIL_TOUPPER_/g; s/(?<![A-Za-z0-9_])evutil_tv_to_msec(?![A-Za-z0-9_])/evutil_tv_to_msec_/g; s/(?<![A-Za-z0-9_])evutil_usleep(?![A-Za-z0-9_])/evutil_usleep_/g; s/(?<![A-Za-z0-9_])ht_improve_hash(?![A-Za-z0-9_])/ht_improve_hash_/g; s/(?<![A-Za-z0-9_])ht_string_hash(?![A-Za-z0-9_])/ht_string_hash_/g; s/(?<![A-Za-z0-9_])min_heap_adjust(?![A-Za-z0-9_])/min_heap_adjust_/g; s/(?<![A-Za-z0-9_])min_heap_ctor(?![A-Za-z0-9_])/min_heap_ctor_/g; s/(?<![A-Za-z0-9_])min_heap_dtor(?![A-Za-z0-9_])/min_heap_dtor_/g; s/(?<![A-Za-z0-9_])min_heap_elem_init(?![A-Za-z0-9_])/min_heap_elem_init_/g; s/(?<![A-Za-z0-9_])min_heap_elt_is_top(?![A-Za-z0-9_])/min_heap_elt_is_top_/g; s/(?<![A-Za-z0-9_])min_heap_empty(?![A-Za-z0-9_])/min_heap_empty_/g; s/(?<![A-Za-z0-9_])min_heap_erase(?![A-Za-z0-9_])/min_heap_erase_/g; s/(?<![A-Za-z0-9_])min_heap_pop(?![A-Za-z0-9_])/min_heap_pop_/g; s/(?<![A-Za-z0-9_])min_heap_push(?![A-Za-z0-9_])/min_heap_push_/g; s/(?<![A-Za-z0-9_])min_heap_reserve(?![A-Za-z0-9_])/min_heap_reserve_/g; s/(?<![A-Za-z0-9_])min_heap_size(?![A-Za-z0-9_])/min_heap_size_/g; s/(?<![A-Za-z0-9_])min_heap_top(?![A-Za-z0-9_])/min_heap_top_/g;
2012-02-29 15:07:33 -05:00
evutil_socket_connect_(&fd1, (struct sockaddr*)&ss1, slen1);
evutil_socket_connect_(&fd2, (struct sockaddr*)&ss1, slen1);
evutil_socket_connect_(&fd3, (struct sockaddr*)&ss2, slen2);
#ifdef _WIN32
Sleep(100); /* XXXX this is a stupid stopgap. */
#endif
event_base_dispatch(base);
tt_int_op(count1, ==, 0);
tt_int_op(count2, ==, 0);
end:
if (fd1>=0)
EVUTIL_CLOSESOCKET(fd1);
if (fd2>=0)
EVUTIL_CLOSESOCKET(fd2);
if (fd3>=0)
EVUTIL_CLOSESOCKET(fd3);
if (listener1)
evconnlistener_free(listener1);
if (listener2)
evconnlistener_free(listener2);
}
static void
errorcb(struct evconnlistener *lis, void *data_)
{
int *data = data_;
*data = 1000;
evconnlistener_disable(lis);
}
static void
regress_listener_error(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
int count = 1;
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE;
if (data->setup_data && strstr((char*)data->setup_data, "ts")) {
flags |= LEV_OPT_THREADSAFE;
}
/* send, so that pair[0] will look 'readable'*/
tt_int_op(send(data->pair[1], "hello", 5, 0), >, 0);
/* Start a listener with a bogus socket. */
listener = evconnlistener_new(base, acceptcb, &count,
flags, 0,
data->pair[0]);
tt_assert(listener);
evconnlistener_set_error_cb(listener, errorcb);
tt_assert(listener);
event_base_dispatch(base);
tt_int_op(count,==,1000); /* set by error cb */
end:
if (listener)
evconnlistener_free(listener);
}
static void
acceptcb_free(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *addr, int socklen, void *arg)
{
int *ptr = arg;
--*ptr;
TT_BLATHER(("Got one for %p", ptr));
evutil_closesocket(fd);
if (! *ptr)
evconnlistener_free(listener);
}
static void
regress_listener_close_accepted_fd(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
struct sockaddr_in sin;
struct sockaddr_storage ss;
ev_socklen_t slen = sizeof(ss);
int count = 1;
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE;
evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = 0; /* "You pick!" */
/* Start a listener with a bogus socket. */
listener = evconnlistener_new_bind(base, acceptcb_free, &count,
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
tt_assert(listener);
tt_assert(getsockname(evconnlistener_get_fd(listener),
(struct sockaddr*)&ss, &slen) == 0);
evutil_socket_connect_(&fd, (struct sockaddr*)&ss, slen);
event_base_dispatch(base);
end:
;
}
static void
regress_listener_immediate_close(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
struct sockaddr_in sin;
struct sockaddr_storage ss;
ev_socklen_t slen = sizeof(ss);
int count = 1;
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE;
evutil_socket_t fd1 = EVUTIL_INVALID_SOCKET, fd2 = EVUTIL_INVALID_SOCKET;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = 0; /* "You pick!" */
/* Start a listener with a bogus socket. */
listener = evconnlistener_new_bind(base, acceptcb, &count,
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
tt_assert(listener);
tt_assert(getsockname(evconnlistener_get_fd(listener),
(struct sockaddr*)&ss, &slen) == 0);
evutil_socket_connect_(&fd1, (struct sockaddr*)&ss, slen);
evutil_socket_connect_(&fd2, (struct sockaddr*)&ss, slen);
event_base_dispatch(base);
tt_int_op(count, ==, 0);
end:
if (listener)
evconnlistener_free(listener);
}
#ifdef EVENT__HAVE_SETRLIMIT
static void
regress_listener_error_unlock(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
unsigned int flags =
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE;
tt_int_op(send(data->pair[1], "hello", 5, 0), >, 0);
/* Start a listener with a bogus socket. */
listener = evconnlistener_new(base, acceptcb, NULL, flags, 0, data->pair[0]);
tt_assert(listener);
/** accept() must errored out with EMFILE */
{
struct rlimit rl;
rl.rlim_cur = rl.rlim_max = data->pair[1];
if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
TT_DIE(("Can't change RLIMIT_NOFILE"));
}
}
event_base_loop(base, EVLOOP_ONCE);
/** with lock debugging, can fail on lock->count assertion */
end:
if (listener)
evconnlistener_free(listener);
}
#endif
Fix deadlock in case of evconnlistener_disable() in parallel with callback I've got an issue when stop evconnlistener not in the event_base_loop() thread. evconnlistener_disable() acquired lev->lock, if the same time, user callbacks is runing, the event thread released lock, after callback finished, it try to aquire the lock again, I think this makes conflict: Here is backtraces: thread 1: 0 __lll_lock_wait (futex=futex@entry=0x555555559a60, private=0) at lowlevellock.c:52 1 0x00007ffff7f2a131 in __GI___pthread_mutex_lock (mutex=0x555555559a60) at ../nptl/pthread_mutex_lock.c:115 2 0x00007ffff7f424c9 in evthread_posix_lock (mode=0, lock_=0x555555559a60) at evthread_pthread.c:79 3 0x00007ffff7f7dc12 in listener_read_cb (fd=7, what=2, p=0x5555555599a0) at listener.c:439 4 0x00007ffff7f6d758 in event_persist_closure (base=0x555555559370, ev=0x5555555599d8) at event.c:1645 5 0x00007ffff7f6da60 in event_process_active_single_queue (base=0x555555559370, activeq=0x5555555597e0, max_to_process=2147483647, endtime=0x0) at event.c:1704 6 0x00007ffff7f6e018 in event_process_active (base=0x555555559370) at event.c:1805 7 0x00007ffff7f6e92a in event_base_loop (base=0x555555559370, flags=0) at event.c:2047 8 0x0000555555555449 in main () at test_listen.c:67 thread 2: 0 futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x555555559858) at ../sysdeps/nptl/futex-internal.h:183 1 __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555555559800, cond=0x555555559830) at pthread_cond_wait.c:508 2 __pthread_cond_wait (cond=0x555555559830, mutex=0x555555559800) at pthread_cond_wait.c:638 3 0x00007ffff7f426f3 in evthread_posix_cond_wait (cond_=0x555555559830, lock_=0x555555559800, tv=0x0) at evthread_pthread.c:162 4 0x00007ffff7f70bc5 in event_del_nolock_ (ev=0x5555555599d8, blocking=2) at event.c:2934 5 0x00007ffff7f70748 in event_del_ (ev=0x5555555599d8, blocking=2) at event.c:2821 6 0x00007ffff7f707a1 in event_del (ev=0x5555555599d8) at event.c:2830 7 0x00007ffff7f7d76e in event_listener_disable (lev=0x5555555599a0) at listener.c:343 8 0x00007ffff7f7d6e5 in evconnlistener_disable (lev=0x5555555599a0) at listener.c:325 9 0x00005555555552c3 in disable_thread (arg=0x5555555599a0) at test_listen.c:27 10 0x00007ffff7f27609 in start_thread (arg=<optimized out>) at pthread_create.c:477 11 0x00007ffff7e4e293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
2021-11-17 08:40:40 +08:00
#ifndef EVENT__DISABLE_THREAD_SUPPORT
static THREAD_FN
disable_thread(void * arg)
{
struct evconnlistener *lev = (struct evconnlistener *)arg;
evconnlistener_disable(lev);
THREAD_RETURN();
Fix deadlock in case of evconnlistener_disable() in parallel with callback I've got an issue when stop evconnlistener not in the event_base_loop() thread. evconnlistener_disable() acquired lev->lock, if the same time, user callbacks is runing, the event thread released lock, after callback finished, it try to aquire the lock again, I think this makes conflict: Here is backtraces: thread 1: 0 __lll_lock_wait (futex=futex@entry=0x555555559a60, private=0) at lowlevellock.c:52 1 0x00007ffff7f2a131 in __GI___pthread_mutex_lock (mutex=0x555555559a60) at ../nptl/pthread_mutex_lock.c:115 2 0x00007ffff7f424c9 in evthread_posix_lock (mode=0, lock_=0x555555559a60) at evthread_pthread.c:79 3 0x00007ffff7f7dc12 in listener_read_cb (fd=7, what=2, p=0x5555555599a0) at listener.c:439 4 0x00007ffff7f6d758 in event_persist_closure (base=0x555555559370, ev=0x5555555599d8) at event.c:1645 5 0x00007ffff7f6da60 in event_process_active_single_queue (base=0x555555559370, activeq=0x5555555597e0, max_to_process=2147483647, endtime=0x0) at event.c:1704 6 0x00007ffff7f6e018 in event_process_active (base=0x555555559370) at event.c:1805 7 0x00007ffff7f6e92a in event_base_loop (base=0x555555559370, flags=0) at event.c:2047 8 0x0000555555555449 in main () at test_listen.c:67 thread 2: 0 futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x555555559858) at ../sysdeps/nptl/futex-internal.h:183 1 __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555555559800, cond=0x555555559830) at pthread_cond_wait.c:508 2 __pthread_cond_wait (cond=0x555555559830, mutex=0x555555559800) at pthread_cond_wait.c:638 3 0x00007ffff7f426f3 in evthread_posix_cond_wait (cond_=0x555555559830, lock_=0x555555559800, tv=0x0) at evthread_pthread.c:162 4 0x00007ffff7f70bc5 in event_del_nolock_ (ev=0x5555555599d8, blocking=2) at event.c:2934 5 0x00007ffff7f70748 in event_del_ (ev=0x5555555599d8, blocking=2) at event.c:2821 6 0x00007ffff7f707a1 in event_del (ev=0x5555555599d8) at event.c:2830 7 0x00007ffff7f7d76e in event_listener_disable (lev=0x5555555599a0) at listener.c:343 8 0x00007ffff7f7d6e5 in evconnlistener_disable (lev=0x5555555599a0) at listener.c:325 9 0x00005555555552c3 in disable_thread (arg=0x5555555599a0) at test_listen.c:27 10 0x00007ffff7f27609 in start_thread (arg=<optimized out>) at pthread_create.c:477 11 0x00007ffff7e4e293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
2021-11-17 08:40:40 +08:00
}
static void
acceptcb_for_thread_test(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *addr, int socklen, void *arg)
{
THREAD_T *threadid_arg;
THREAD_T threadid;
struct timeval delay = { .tv_sec = 0, .tv_usec = 5000 };
threadid_arg = (THREAD_T *)arg;
evutil_closesocket(fd);
/* We need to run evconnlistener_disable() from disable_thread
* in parallel with processing this callback to trigger deadlock regression
*/
THREAD_START(threadid, disable_thread, listener);
evutil_usleep_(&delay);
*threadid_arg = threadid;
}
static void
regress_listener_disable_in_thread(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
struct sockaddr_in sin;
struct sockaddr_storage ss;
ev_socklen_t slen = sizeof(ss);
evutil_socket_t fd = EVUTIL_INVALID_SOCKET;
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE;
THREAD_T threadid;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = 0; /* "You pick!" */
listener = evconnlistener_new_bind(base, acceptcb_for_thread_test, (void*)(&threadid),
flags, -1, (struct sockaddr *)&sin, sizeof(sin));
tt_assert(listener);
tt_assert(getsockname(evconnlistener_get_fd(listener),
(struct sockaddr*)&ss, &slen) == 0);
tt_assert(evutil_socket_connect_(&fd, (struct sockaddr*)&ss, slen) != -1);
event_base_loop(base, EVLOOP_ONCE);
THREAD_JOIN(threadid);
end:
if (listener)
evconnlistener_free(listener);
}
static void
errorcb_for_thread_test(struct evconnlistener *listener, void *arg)
{
THREAD_T *threadid_arg;
THREAD_T threadid;
struct timeval delay = { .tv_sec = 0, .tv_usec = 5000 };
threadid_arg = (THREAD_T *)arg;
/* We need to run evconnlistener_disable() from disable_thread
* in parallel with processing this callback to trigger deadlock regression
*/
THREAD_START(threadid, disable_thread, listener);
evutil_usleep_(&delay);
*threadid_arg = threadid;
}
static void
acceptcb_for_thread_test_error(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *addr, int socklen, void *arg)
{
}
static void
regress_listener_disable_in_thread_error(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
unsigned int flags = LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_THREADSAFE;
THREAD_T threadid;
/* send, so that pair[0] will look 'readable'*/
tt_int_op(send(data->pair[1], "hello", 5, 0), >, 0);
/* Start a listener with a bogus socket. */
listener = evconnlistener_new(base, acceptcb_for_thread_test_error, (void*)&threadid,
flags, 0,
data->pair[0]);
tt_assert(listener);
evconnlistener_set_error_cb(listener, errorcb_for_thread_test);
event_base_loop(base, EVLOOP_ONCE);
THREAD_JOIN(threadid);
end:
if (listener)
evconnlistener_free(listener);
}
#endif
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
#ifdef _WIN32
static int
is_unicode_temp_path()
{
DWORD n;
WCHAR short_temp_path[MAX_PATH];
WCHAR long_temp_path[MAX_PATH];
n = GetTempPathW(MAX_PATH, short_temp_path);
if (n == 0 || n > MAX_PATH)
return 1;
n = GetLongPathNameW(short_temp_path, long_temp_path, MAX_PATH);
if (n == 0 || n > MAX_PATH)
return 1;
// If it contains valid wide characters, it is considered Unicode.
for (const wchar_t* p = long_temp_path; *p != L'\0'; ++p) {
if (*p > 127) { // Non-ASCII character
return 1; // It's a Unicode path
}
}
return 0; // No non-ASCII characters found, may not be Unicode
}
#endif
static void
empty_listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
struct sockaddr *sa, int socklen, void *user_data)
{
printf("Empty listener, do nothing about it!\n");
}
static void
regress_listener_reuseport_on_unix_socket(void *arg)
{
struct basic_test_data *data = arg;
struct event_base *base = data->base;
struct evconnlistener *listener = NULL;
char *socket_path = NULL;
int truncated_temp_file = 0;
struct sockaddr_un addr;
int tempfd;
tempfd = regress_make_tmpfile("", 0, &socket_path);
/* On Windows, if TMP environment variable is corrupted, we may not be
* able create temporary file, just skip it */
if (tempfd < 0)
tt_skip();
TT_BLATHER(("Temporary socket path: %s, fd: %i", socket_path, tempfd));
#if defined(_WIN32) && defined(EVENT__HAVE_AFUNIX_H)
if (evutil_check_working_afunix_() == 0)
/* AF_UNIX is not available on the current Windows platform,
* just skip this test. */
tt_skip();
#endif
/* close fd to avoid leaks, since we only need a temporary file path
* for bind() to create a socket file. */
close(tempfd);
/* For security reason, we must delete any existing sockets in the filesystem.
* Besides, we will get EADDRINUSE error if the socket file already exists. */
unlink(socket_path);
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
if (strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path)) >= sizeof(addr.sun_path))
/* The temporary path exceeds the system limit, we may need to adjust some subsequent
* assertions accordingly to ensure the success of this test. */
truncated_temp_file = 1;
listener = evconnlistener_new_bind(base, empty_listener_cb, (void *)base,
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&addr, sizeof(addr));
tt_assert_msg(listener == NULL, "AF_UNIX listener shouldn't use SO_REUSEADDR!");
listener = evconnlistener_new_bind(base, empty_listener_cb, (void *)base,
LEV_OPT_REUSEABLE_PORT|LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&addr, sizeof(addr));
tt_assert_msg(listener == NULL, "AF_UNIX listener shouldn't use SO_REUSEPORT!");
/* Create a AF_UNIX listener without reusing address or port. */
listener = evconnlistener_new_bind(base, empty_listener_cb, (void *)base,
LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&addr, sizeof(addr));
if (truncated_temp_file) {
tt_assert_msg(listener == NULL, "Should not create a AF_UNIX listener with truncated socket path!");
} else {
#ifdef _WIN32
if (listener == NULL && WSAENETDOWN == EVUTIL_SOCKET_ERROR() && is_unicode_temp_path())
/* TODO(panjf2000): this error kept happening on the GitHub Runner of
* (windows-latest, UNOCODE_TEMPORARY_DIRECTORY) disturbingly and the
* root cause still remains unknown.
* Thus, we skip this for now, but try to dive deep and figure out the
* root cause later. */
tt_skip();
#endif
tt_assert_msg(listener, "Could not create a AF_UNIX listener normally!");
}
end:
if (socket_path) {
unlink(socket_path);
free(socket_path);
}
if (listener)
evconnlistener_free(listener);
}
#endif
struct testcase_t listener_testcases[] = {
{ "randport", regress_pick_a_port, TT_FORK|TT_NEED_BASE,
&basic_setup, NULL},
{ "randport_ts", regress_pick_a_port, TT_FORK|TT_NEED_BASE,
&basic_setup, (char*)"ts"},
#ifdef EVENT__HAVE_SETRLIMIT
{ "error_unlock", regress_listener_error_unlock,
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_NO_LOGS,
&basic_setup, NULL},
#endif
{ "error", regress_listener_error,
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR,
&basic_setup, NULL},
{ "error_ts", regress_listener_error,
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR,
&basic_setup, (char*)"ts"},
{ "close_accepted_fd", regress_listener_close_accepted_fd,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL, },
{ "immediate_close", regress_listener_immediate_close,
TT_FORK|TT_NEED_BASE, &basic_setup, NULL, },
Fix deadlock in case of evconnlistener_disable() in parallel with callback I've got an issue when stop evconnlistener not in the event_base_loop() thread. evconnlistener_disable() acquired lev->lock, if the same time, user callbacks is runing, the event thread released lock, after callback finished, it try to aquire the lock again, I think this makes conflict: Here is backtraces: thread 1: 0 __lll_lock_wait (futex=futex@entry=0x555555559a60, private=0) at lowlevellock.c:52 1 0x00007ffff7f2a131 in __GI___pthread_mutex_lock (mutex=0x555555559a60) at ../nptl/pthread_mutex_lock.c:115 2 0x00007ffff7f424c9 in evthread_posix_lock (mode=0, lock_=0x555555559a60) at evthread_pthread.c:79 3 0x00007ffff7f7dc12 in listener_read_cb (fd=7, what=2, p=0x5555555599a0) at listener.c:439 4 0x00007ffff7f6d758 in event_persist_closure (base=0x555555559370, ev=0x5555555599d8) at event.c:1645 5 0x00007ffff7f6da60 in event_process_active_single_queue (base=0x555555559370, activeq=0x5555555597e0, max_to_process=2147483647, endtime=0x0) at event.c:1704 6 0x00007ffff7f6e018 in event_process_active (base=0x555555559370) at event.c:1805 7 0x00007ffff7f6e92a in event_base_loop (base=0x555555559370, flags=0) at event.c:2047 8 0x0000555555555449 in main () at test_listen.c:67 thread 2: 0 futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x555555559858) at ../sysdeps/nptl/futex-internal.h:183 1 __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555555559800, cond=0x555555559830) at pthread_cond_wait.c:508 2 __pthread_cond_wait (cond=0x555555559830, mutex=0x555555559800) at pthread_cond_wait.c:638 3 0x00007ffff7f426f3 in evthread_posix_cond_wait (cond_=0x555555559830, lock_=0x555555559800, tv=0x0) at evthread_pthread.c:162 4 0x00007ffff7f70bc5 in event_del_nolock_ (ev=0x5555555599d8, blocking=2) at event.c:2934 5 0x00007ffff7f70748 in event_del_ (ev=0x5555555599d8, blocking=2) at event.c:2821 6 0x00007ffff7f707a1 in event_del (ev=0x5555555599d8) at event.c:2830 7 0x00007ffff7f7d76e in event_listener_disable (lev=0x5555555599a0) at listener.c:343 8 0x00007ffff7f7d6e5 in evconnlistener_disable (lev=0x5555555599a0) at listener.c:325 9 0x00005555555552c3 in disable_thread (arg=0x5555555599a0) at test_listen.c:27 10 0x00007ffff7f27609 in start_thread (arg=<optimized out>) at pthread_create.c:477 11 0x00007ffff7e4e293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
2021-11-17 08:40:40 +08:00
#ifndef EVENT__DISABLE_THREAD_SUPPORT
{ "disable_in_thread", regress_listener_disable_in_thread,
TT_FORK|TT_NEED_BASE|TT_NEED_THREADS,
&basic_setup, NULL, },
{ "disable_in_thread_error", regress_listener_disable_in_thread_error,
TT_FORK|TT_NEED_BASE|TT_NEED_THREADS|TT_NEED_SOCKETPAIR,
&basic_setup, NULL, },
#endif
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_UN
{ "reuseport_on_unix_socket", regress_listener_reuseport_on_unix_socket,
TT_FORK|TT_NEED_BASE,
&basic_setup, NULL, },
#endif
END_OF_TESTCASES,
};
struct testcase_t listener_iocp_testcases[] = {
{ "randport", regress_pick_a_port,
TT_FORK|TT_NEED_BASE|TT_ENABLE_IOCP,
&basic_setup, NULL},
{ "error", regress_listener_error,
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR|TT_ENABLE_IOCP,
&basic_setup, NULL},
END_OF_TESTCASES,
};