mirror of https://github.com/lukechilds/node.git
59 changed files with 1970 additions and 2144 deletions
File diff suppressed because it is too large
@ -1,22 +0,0 @@ |
|||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) |
|
||||
include_directories(${node_platform}-${cares_arch}) |
|
||||
add_definitions(-DHAVE_CONFIG_H=1) |
|
||||
|
|
||||
include(CheckLibraryExists) |
|
||||
check_library_exists(socket socket "" HAVE_SOCKET_LIB) |
|
||||
check_library_exists(nsl gethostbyname "" HAVE_NSL_LIB) |
|
||||
|
|
||||
file(GLOB lib_sources *.c) |
|
||||
add_library(cares ${lib_sources}) |
|
||||
|
|
||||
if(${HAVE_SOCKET_LIB}) |
|
||||
set(cares_libs ${cares_libs} socket) |
|
||||
endif() |
|
||||
|
|
||||
if(${HAVE_NSL_LIB}) |
|
||||
set(cares_libs ${cares_libs} nsl) |
|
||||
endif() |
|
||||
|
|
||||
if(cares_libs) |
|
||||
target_link_libraries(cares ${cares_libs}) |
|
||||
endif() |
|
@ -1,21 +0,0 @@ |
|||||
Library: c-ares, DNS resolver |
|
||||
|
|
||||
Version: 1.7.3 (11 June, 2010) |
|
||||
|
|
||||
Authors: Greg Hudson, Daniel Stenberg |
|
||||
|
|
||||
License: MIT |
|
||||
|
|
||||
Notes: |
|
||||
|
|
||||
Just use waf instead of the autoconf based configure script. Delete most of |
|
||||
the documentation and other files distributed with it. To upgrade, run |
|
||||
./configure on linux, macintosh, solaris (and other supported platforms) and |
|
||||
copy |
|
||||
- ares_config.h |
|
||||
- ares_setup.h |
|
||||
- ares_build.h |
|
||||
into the appropriate directory. |
|
||||
|
|
||||
|
|
||||
|
|
@ -1,26 +1,16 @@ |
|||||
c-ares version 1.7.5 |
c-ares version 1.9.0 |
||||
|
|
||||
Fixed: |
Changed: |
||||
|
|
||||
|
o Added ares_parse_soa_reply |
||||
|
|
||||
o detection of semicolon comments in resolv.conf |
Fixed: |
||||
o avoid using system's inet_net_pton affected by the WLB-2008080064 advisory |
|
||||
o replacement ares_inet_net_pton affected by the WLB-2008080064 advisory |
|
||||
o replacement ares_inet_ntop affected by potential out of bounds write |
|
||||
o added install target to Makefile.msvc |
|
||||
o only fall back to AF_INET searches when looking for AF_UNSPEC addresses |
|
||||
o fixed ares_parse_*_reply memory leaks |
|
||||
o Use correct sizeof in ares_getnameinfo() |
|
||||
o IPv6-on-windows: find DNS servers correctly |
|
||||
o man pages: docs for the c-ares utility programs |
|
||||
o getservbyport replacement for Win CE |
|
||||
o config_sortlist: (win32) missing else |
|
||||
o advance_tcp_send_queue: avoid NULL ptr dereference |
|
||||
o configure: fix a bashism |
|
||||
o ares_expand_name: Fix encoded length for indirect root |
|
||||
|
|
||||
|
o libcares.pc generation for static MingW* cross builds |
||||
|
o ares_dup: UDP and TCP port byte order in saved options |
||||
|
|
||||
Thanks go to these friendly people for their efforts and contributions: |
Thanks go to these friendly people for their efforts and contributions: |
||||
|
|
||||
Yang Tse, Jakub Hrozek, Gisle Vanem, Tom Hughes, David Stuart, Dima Tisnek, |
Yang Tse, Nick Alcock, Marko Kreen |
||||
Peter Pentchev, Stefan Buhler |
|
||||
|
|
||||
Have fun! |
Have fun! |
||||
|
File diff suppressed because it is too large
@ -0,0 +1,188 @@ |
|||||
|
|
||||
|
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||
|
* Copyright (C) 2009 by Jakub Hrozek <jhrozek@redhat.com> |
||||
|
* |
||||
|
* Permission to use, copy, modify, and distribute this |
||||
|
* software and its documentation for any purpose and without |
||||
|
* fee is hereby granted, provided that the above copyright |
||||
|
* notice appear in all copies and that both that copyright |
||||
|
* notice and this permission notice appear in supporting |
||||
|
* documentation, and that the name of M.I.T. not be used in |
||||
|
* advertising or publicity pertaining to distribution of the |
||||
|
* software without specific, written prior permission. |
||||
|
* M.I.T. makes no representations about the suitability of |
||||
|
* this software for any purpose. It is provided "as is" |
||||
|
* without express or implied warranty. |
||||
|
*/ |
||||
|
|
||||
|
#include "ares_setup.h" |
||||
|
|
||||
|
#ifdef HAVE_SYS_SOCKET_H |
||||
|
# include <sys/socket.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_NETINET_IN_H |
||||
|
# include <netinet/in.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_NETDB_H |
||||
|
# include <netdb.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_ARPA_INET_H |
||||
|
# include <arpa/inet.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_ARPA_NAMESER_H |
||||
|
# include <arpa/nameser.h> |
||||
|
#else |
||||
|
# include "nameser.h" |
||||
|
#endif |
||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H |
||||
|
# include <arpa/nameser_compat.h> |
||||
|
#endif |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include "ares.h" |
||||
|
#include "ares_dns.h" |
||||
|
#include "ares_data.h" |
||||
|
#include "ares_private.h" |
||||
|
|
||||
|
/* AIX portability check */ |
||||
|
#ifndef T_NAPTR |
||||
|
#define T_NAPTR 35 /* naming authority pointer */ |
||||
|
#endif |
||||
|
|
||||
|
int |
||||
|
ares_parse_naptr_reply (const unsigned char *abuf, int alen, |
||||
|
struct ares_naptr_reply **naptr_out) |
||||
|
{ |
||||
|
unsigned int qdcount, ancount, i; |
||||
|
const unsigned char *aptr, *vptr; |
||||
|
int status, rr_type, rr_class, rr_len; |
||||
|
long len; |
||||
|
char *hostname = NULL, *rr_name = NULL; |
||||
|
struct ares_naptr_reply *naptr_head = NULL; |
||||
|
struct ares_naptr_reply *naptr_last = NULL; |
||||
|
struct ares_naptr_reply *naptr_curr; |
||||
|
|
||||
|
/* Set *naptr_out to NULL for all failure cases. */ |
||||
|
*naptr_out = NULL; |
||||
|
|
||||
|
/* Give up if abuf doesn't have room for a header. */ |
||||
|
if (alen < HFIXEDSZ) |
||||
|
return ARES_EBADRESP; |
||||
|
|
||||
|
/* Fetch the question and answer count from the header. */ |
||||
|
qdcount = DNS_HEADER_QDCOUNT (abuf); |
||||
|
ancount = DNS_HEADER_ANCOUNT (abuf); |
||||
|
if (qdcount != 1) |
||||
|
return ARES_EBADRESP; |
||||
|
if (ancount == 0) |
||||
|
return ARES_ENODATA; |
||||
|
|
||||
|
/* Expand the name from the question, and skip past the question. */ |
||||
|
aptr = abuf + HFIXEDSZ; |
||||
|
status = ares_expand_name (aptr, abuf, alen, &hostname, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
return status; |
||||
|
|
||||
|
if (aptr + len + QFIXEDSZ > abuf + alen) |
||||
|
{ |
||||
|
free (hostname); |
||||
|
return ARES_EBADRESP; |
||||
|
} |
||||
|
aptr += len + QFIXEDSZ; |
||||
|
|
||||
|
/* Examine each answer resource record (RR) in turn. */ |
||||
|
for (i = 0; i < ancount; i++) |
||||
|
{ |
||||
|
/* Decode the RR up to the data field. */ |
||||
|
status = ares_expand_name (aptr, abuf, alen, &rr_name, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
aptr += len; |
||||
|
if (aptr + RRFIXEDSZ > abuf + alen) |
||||
|
{ |
||||
|
status = ARES_EBADRESP; |
||||
|
break; |
||||
|
} |
||||
|
rr_type = DNS_RR_TYPE (aptr); |
||||
|
rr_class = DNS_RR_CLASS (aptr); |
||||
|
rr_len = DNS_RR_LEN (aptr); |
||||
|
aptr += RRFIXEDSZ; |
||||
|
|
||||
|
/* Check if we are really looking at a NAPTR record */ |
||||
|
if (rr_class == C_IN && rr_type == T_NAPTR) |
||||
|
{ |
||||
|
/* parse the NAPTR record itself */ |
||||
|
|
||||
|
/* Allocate storage for this NAPTR answer appending it to the list */ |
||||
|
naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY); |
||||
|
if (!naptr_curr) |
||||
|
{ |
||||
|
status = ARES_ENOMEM; |
||||
|
break; |
||||
|
} |
||||
|
if (naptr_last) |
||||
|
{ |
||||
|
naptr_last->next = naptr_curr; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
naptr_head = naptr_curr; |
||||
|
} |
||||
|
naptr_last = naptr_curr; |
||||
|
|
||||
|
vptr = aptr; |
||||
|
naptr_curr->order = DNS__16BIT(vptr); |
||||
|
vptr += sizeof(unsigned short); |
||||
|
naptr_curr->preference = DNS__16BIT(vptr); |
||||
|
vptr += sizeof(unsigned short); |
||||
|
|
||||
|
status = ares_expand_string(vptr, abuf, alen, &naptr_curr->flags, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
break; |
||||
|
vptr += len; |
||||
|
|
||||
|
status = ares_expand_string(vptr, abuf, alen, &naptr_curr->service, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
break; |
||||
|
vptr += len; |
||||
|
|
||||
|
status = ares_expand_string(vptr, abuf, alen, &naptr_curr->regexp, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
break; |
||||
|
vptr += len; |
||||
|
|
||||
|
status = ares_expand_name(vptr, abuf, alen, &naptr_curr->replacement, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
/* Don't lose memory in the next iteration */ |
||||
|
free (rr_name); |
||||
|
rr_name = NULL; |
||||
|
|
||||
|
/* Move on to the next record */ |
||||
|
aptr += rr_len; |
||||
|
} |
||||
|
|
||||
|
if (hostname) |
||||
|
free (hostname); |
||||
|
if (rr_name) |
||||
|
free (rr_name); |
||||
|
|
||||
|
/* clean up on error */ |
||||
|
if (status != ARES_SUCCESS) |
||||
|
{ |
||||
|
if (naptr_head) |
||||
|
ares_free_data (naptr_head); |
||||
|
return status; |
||||
|
} |
||||
|
|
||||
|
/* everything looks fine, return the data */ |
||||
|
*naptr_out = naptr_head; |
||||
|
|
||||
|
return ARES_SUCCESS; |
||||
|
} |
||||
|
|
@ -0,0 +1,135 @@ |
|||||
|
|
||||
|
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
||||
|
* Copyright (C) 2012 Marko Kreen <markokr@gmail.com> |
||||
|
* |
||||
|
* Permission to use, copy, modify, and distribute this |
||||
|
* software and its documentation for any purpose and without |
||||
|
* fee is hereby granted, provided that the above copyright |
||||
|
* notice appear in all copies and that both that copyright |
||||
|
* notice and this permission notice appear in supporting |
||||
|
* documentation, and that the name of M.I.T. not be used in |
||||
|
* advertising or publicity pertaining to distribution of the |
||||
|
* software without specific, written prior permission. |
||||
|
* M.I.T. makes no representations about the suitability of |
||||
|
* this software for any purpose. It is provided "as is" |
||||
|
* without express or implied warranty. |
||||
|
*/ |
||||
|
|
||||
|
#include "ares_setup.h" |
||||
|
|
||||
|
#ifdef HAVE_SYS_SOCKET_H |
||||
|
# include <sys/socket.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_NETINET_IN_H |
||||
|
# include <netinet/in.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_NETDB_H |
||||
|
# include <netdb.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_ARPA_INET_H |
||||
|
# include <arpa/inet.h> |
||||
|
#endif |
||||
|
#ifdef HAVE_ARPA_NAMESER_H |
||||
|
# include <arpa/nameser.h> |
||||
|
#else |
||||
|
# include "nameser.h" |
||||
|
#endif |
||||
|
#ifdef HAVE_ARPA_NAMESER_COMPAT_H |
||||
|
# include <arpa/nameser_compat.h> |
||||
|
#endif |
||||
|
|
||||
|
#include <stdlib.h> |
||||
|
#include <string.h> |
||||
|
#include "ares.h" |
||||
|
#include "ares_dns.h" |
||||
|
#include "ares_data.h" |
||||
|
#include "ares_private.h" |
||||
|
|
||||
|
int |
||||
|
ares_parse_soa_reply(const unsigned char *abuf, int alen, |
||||
|
struct ares_soa_reply **soa_out) |
||||
|
{ |
||||
|
const unsigned char *aptr; |
||||
|
long len; |
||||
|
char *qname = NULL, *rr_name = NULL; |
||||
|
struct ares_soa_reply *soa = NULL; |
||||
|
int qdcount, ancount; |
||||
|
int status; |
||||
|
|
||||
|
if (alen < HFIXEDSZ) |
||||
|
return ARES_EBADRESP; |
||||
|
|
||||
|
/* parse message header */ |
||||
|
qdcount = DNS_HEADER_QDCOUNT(abuf); |
||||
|
ancount = DNS_HEADER_ANCOUNT(abuf); |
||||
|
if (qdcount != 1 || ancount != 1) |
||||
|
return ARES_EBADRESP; |
||||
|
aptr = abuf + HFIXEDSZ; |
||||
|
|
||||
|
/* query name */ |
||||
|
status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
goto failed_stat; |
||||
|
aptr += len; |
||||
|
|
||||
|
/* skip qtype & qclass */ |
||||
|
if (aptr + QFIXEDSZ > abuf + alen) |
||||
|
goto failed; |
||||
|
aptr += QFIXEDSZ; |
||||
|
|
||||
|
/* rr_name */ |
||||
|
status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
goto failed_stat; |
||||
|
aptr += len; |
||||
|
|
||||
|
/* skip rr_type, rr_class, rr_ttl, rr_rdlen */ |
||||
|
if (aptr + RRFIXEDSZ > abuf + alen) |
||||
|
goto failed; |
||||
|
aptr += RRFIXEDSZ; |
||||
|
|
||||
|
/* allocate result struct */ |
||||
|
soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY); |
||||
|
if (!soa) |
||||
|
return ARES_ENOMEM; |
||||
|
|
||||
|
/* nsname */ |
||||
|
status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
goto failed_stat; |
||||
|
aptr += len; |
||||
|
|
||||
|
/* hostmaster */ |
||||
|
status = ares__expand_name_for_response(aptr, abuf, alen, &soa->hostmaster, &len); |
||||
|
if (status != ARES_SUCCESS) |
||||
|
goto failed_stat; |
||||
|
aptr += len; |
||||
|
|
||||
|
/* integer fields */ |
||||
|
if (aptr + 5 * 4 > abuf + alen) |
||||
|
goto failed; |
||||
|
soa->serial = DNS__32BIT(aptr + 0 * 4); |
||||
|
soa->refresh = DNS__32BIT(aptr + 1 * 4); |
||||
|
soa->retry = DNS__32BIT(aptr + 2 * 4); |
||||
|
soa->expire = DNS__32BIT(aptr + 3 * 4); |
||||
|
soa->minttl = DNS__32BIT(aptr + 4 * 4); |
||||
|
|
||||
|
free(qname); |
||||
|
free(rr_name); |
||||
|
|
||||
|
*soa_out = soa; |
||||
|
|
||||
|
return ARES_SUCCESS; |
||||
|
|
||||
|
failed: |
||||
|
status = ARES_EBADRESP; |
||||
|
|
||||
|
failed_stat: |
||||
|
ares_free_data(soa); |
||||
|
if (qname) |
||||
|
free(qname); |
||||
|
if (rr_name) |
||||
|
free(rr_name); |
||||
|
return status; |
||||
|
} |
||||
|
|
@ -0,0 +1,97 @@ |
|||||
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
|
* |
||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
* of this software and associated documentation files (the "Software"), to |
||||
|
* deal in the Software without restriction, including without limitation the |
||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
||||
|
* sell copies of the Software, and to permit persons to whom the Software is |
||||
|
* furnished to do so, subject to the following conditions: |
||||
|
* |
||||
|
* The above copyright notice and this permission notice shall be included in |
||||
|
* all copies or substantial portions of the Software. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||
|
* IN THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include "task.h" |
||||
|
#include "uv.h" |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#define NUM_PINGS (1000 * 1000) |
||||
|
|
||||
|
static unsigned int callbacks; |
||||
|
static volatile int done; |
||||
|
|
||||
|
|
||||
|
static void async_cb(uv_async_t* handle, int status) { |
||||
|
if (++callbacks == NUM_PINGS) |
||||
|
uv_close((uv_handle_t*) handle, NULL); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void pummel(void* arg) { |
||||
|
while (!done) |
||||
|
uv_async_send((uv_async_t*) arg); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static int test_async_pummel(int nthreads) { |
||||
|
uv_thread_t* tids; |
||||
|
uv_async_t handle; |
||||
|
uint64_t time; |
||||
|
int i; |
||||
|
|
||||
|
tids = calloc(nthreads, sizeof(tids[0])); |
||||
|
ASSERT(tids != NULL); |
||||
|
|
||||
|
ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb)); |
||||
|
|
||||
|
for (i = 0; i < nthreads; i++) |
||||
|
ASSERT(0 == uv_thread_create(tids + i, pummel, &handle)); |
||||
|
|
||||
|
time = uv_hrtime(); |
||||
|
|
||||
|
ASSERT(0 == uv_run(uv_default_loop())); |
||||
|
|
||||
|
time = uv_hrtime() - time; |
||||
|
done = 1; |
||||
|
|
||||
|
for (i = 0; i < nthreads; i++) |
||||
|
ASSERT(0 == uv_thread_join(tids + i)); |
||||
|
|
||||
|
printf("%s callbacks in %.2f seconds (%s/sec)\n", |
||||
|
fmt(callbacks), |
||||
|
time / 1e9, |
||||
|
fmt(callbacks / (time / 1e9))); |
||||
|
|
||||
|
free(tids); |
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async_pummel_1) { |
||||
|
return test_async_pummel(1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async_pummel_2) { |
||||
|
return test_async_pummel(2); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async_pummel_4) { |
||||
|
return test_async_pummel(4); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async_pummel_8) { |
||||
|
return test_async_pummel(8); |
||||
|
} |
@ -0,0 +1,137 @@ |
|||||
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
|
* |
||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
* of this software and associated documentation files (the "Software"), to |
||||
|
* deal in the Software without restriction, including without limitation the |
||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
||||
|
* sell copies of the Software, and to permit persons to whom the Software is |
||||
|
* furnished to do so, subject to the following conditions: |
||||
|
* |
||||
|
* The above copyright notice and this permission notice shall be included in |
||||
|
* all copies or substantial portions of the Software. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
||||
|
* IN THE SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include "task.h" |
||||
|
#include "uv.h" |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <stdlib.h> |
||||
|
|
||||
|
#define NUM_PINGS (1000 * 1000) |
||||
|
|
||||
|
struct ctx { |
||||
|
uv_loop_t* loop; |
||||
|
uv_thread_t thread; |
||||
|
uv_async_t main_async; /* wake up main thread */ |
||||
|
uv_async_t worker_async; /* wake up worker */ |
||||
|
unsigned int nthreads; |
||||
|
unsigned int main_sent; |
||||
|
unsigned int main_seen; |
||||
|
unsigned int worker_sent; |
||||
|
unsigned int worker_seen; |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
static void worker_async_cb(uv_async_t* handle, int status) { |
||||
|
struct ctx* ctx = container_of(handle, struct ctx, worker_async); |
||||
|
|
||||
|
ASSERT(0 == uv_async_send(&ctx->main_async)); |
||||
|
ctx->worker_sent++; |
||||
|
ctx->worker_seen++; |
||||
|
|
||||
|
if (ctx->worker_sent >= NUM_PINGS) |
||||
|
uv_close((uv_handle_t*) &ctx->worker_async, NULL); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void main_async_cb(uv_async_t* handle, int status) { |
||||
|
struct ctx* ctx = container_of(handle, struct ctx, main_async); |
||||
|
|
||||
|
ASSERT(0 == uv_async_send(&ctx->worker_async)); |
||||
|
ctx->main_sent++; |
||||
|
ctx->main_seen++; |
||||
|
|
||||
|
if (ctx->main_sent >= NUM_PINGS) |
||||
|
uv_close((uv_handle_t*) &ctx->main_async, NULL); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void worker(void* arg) { |
||||
|
struct ctx* ctx = arg; |
||||
|
ASSERT(0 == uv_async_send(&ctx->main_async)); |
||||
|
ASSERT(0 == uv_run(ctx->loop)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static int test_async(int nthreads) { |
||||
|
struct ctx* threads; |
||||
|
struct ctx* ctx; |
||||
|
uint64_t time; |
||||
|
int i; |
||||
|
|
||||
|
threads = calloc(nthreads, sizeof(threads[0])); |
||||
|
ASSERT(threads != NULL); |
||||
|
|
||||
|
for (i = 0; i < nthreads; i++) { |
||||
|
ctx = threads + i; |
||||
|
ctx->nthreads = nthreads; |
||||
|
ctx->loop = uv_loop_new(); |
||||
|
ASSERT(ctx->loop != NULL); |
||||
|
ASSERT(0 == uv_async_init(ctx->loop, &ctx->worker_async, worker_async_cb)); |
||||
|
ASSERT(0 == uv_async_init(uv_default_loop(), &ctx->main_async, main_async_cb)); |
||||
|
ASSERT(0 == uv_thread_create(&ctx->thread, worker, ctx)); |
||||
|
} |
||||
|
|
||||
|
time = uv_hrtime(); |
||||
|
|
||||
|
ASSERT(0 == uv_run(uv_default_loop())); |
||||
|
|
||||
|
for (i = 0; i < nthreads; i++) |
||||
|
ASSERT(0 == uv_thread_join(&threads[i].thread)); |
||||
|
|
||||
|
time = uv_hrtime() - time; |
||||
|
|
||||
|
for (i = 0; i < nthreads; i++) { |
||||
|
ctx = threads + i; |
||||
|
ASSERT(ctx->worker_sent == NUM_PINGS); |
||||
|
ASSERT(ctx->worker_seen == NUM_PINGS); |
||||
|
ASSERT(ctx->main_sent == (unsigned int) NUM_PINGS); |
||||
|
ASSERT(ctx->main_seen == (unsigned int) NUM_PINGS); |
||||
|
} |
||||
|
|
||||
|
printf("%.2f sec (%s/sec)\n", |
||||
|
time / 1e9, |
||||
|
fmt(NUM_PINGS / (time / 1e9))); |
||||
|
|
||||
|
free(threads); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async1) { |
||||
|
return test_async(1); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async2) { |
||||
|
return test_async(2); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async4) { |
||||
|
return test_async(4); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BENCHMARK_IMPL(async8) { |
||||
|
return test_async(8); |
||||
|
} |
@ -1,111 +0,0 @@ |
|||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||
* |
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|
||||
* of this software and associated documentation files (the "Software"), to |
|
||||
* deal in the Software without restriction, including without limitation the |
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
|
||||
* sell copies of the Software, and to permit persons to whom the Software is |
|
||||
* furnished to do so, subject to the following conditions: |
|
||||
* |
|
||||
* The above copyright notice and this permission notice shall be included in |
|
||||
* all copies or substantial portions of the Software. |
|
||||
* |
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
|
||||
* IN THE SOFTWARE. |
|
||||
*/ |
|
||||
|
|
||||
#include "uv.h" |
|
||||
#include "task.h" |
|
||||
|
|
||||
static uv_check_t check_handle; |
|
||||
static uv_timer_t timer_handle; |
|
||||
static uv_tcp_t server_handle; |
|
||||
static uv_tcp_t client_handle; |
|
||||
static uv_tcp_t peer_handle; |
|
||||
static uv_write_t write_req; |
|
||||
static uv_connect_t connect_req; |
|
||||
|
|
||||
static unsigned long ticks; /* event loop ticks */ |
|
||||
|
|
||||
|
|
||||
static void check_cb(uv_check_t* handle, int status) { |
|
||||
ticks++; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static void timer_cb(uv_timer_t* handle, int status) { |
|
||||
uv_close((uv_handle_t*) &check_handle, NULL); |
|
||||
uv_close((uv_handle_t*) &timer_handle, NULL); |
|
||||
uv_close((uv_handle_t*) &server_handle, NULL); |
|
||||
uv_close((uv_handle_t*) &client_handle, NULL); |
|
||||
uv_close((uv_handle_t*) &peer_handle, NULL); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) { |
|
||||
ASSERT(0 && "alloc_cb should not have been called"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static void read_cb(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { |
|
||||
ASSERT(0 && "read_cb should not have been called"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static void connect_cb(uv_connect_t* req, int status) { |
|
||||
ASSERT(req->handle == (uv_stream_t*) &client_handle); |
|
||||
ASSERT(0 == status); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static void write_cb(uv_write_t* req, int status) { |
|
||||
ASSERT(req->handle == (uv_stream_t*) &peer_handle); |
|
||||
ASSERT(0 == status); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static void connection_cb(uv_stream_t* handle, int status) { |
|
||||
uv_buf_t buf; |
|
||||
|
|
||||
buf = uv_buf_init("PING", 4); |
|
||||
|
|
||||
ASSERT(0 == status); |
|
||||
ASSERT(0 == uv_tcp_init(uv_default_loop(), &peer_handle)); |
|
||||
ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); |
|
||||
ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb)); |
|
||||
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &peer_handle, |
|
||||
&buf, 1, write_cb)); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
TEST_IMPL(tcp_unexpected_read) { |
|
||||
struct sockaddr_in addr; |
|
||||
uv_loop_t* loop; |
|
||||
|
|
||||
addr = uv_ip4_addr("127.0.0.1", TEST_PORT); |
|
||||
loop = uv_default_loop(); |
|
||||
|
|
||||
ASSERT(0 == uv_timer_init(loop, &timer_handle)); |
|
||||
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1000, 0)); |
|
||||
ASSERT(0 == uv_check_init(loop, &check_handle)); |
|
||||
ASSERT(0 == uv_check_start(&check_handle, check_cb)); |
|
||||
ASSERT(0 == uv_tcp_init(loop, &server_handle)); |
|
||||
ASSERT(0 == uv_tcp_init(loop, &client_handle)); |
|
||||
ASSERT(0 == uv_tcp_bind(&server_handle, addr)); |
|
||||
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); |
|
||||
ASSERT(0 == uv_tcp_connect(&connect_req, &client_handle, addr, connect_cb)); |
|
||||
ASSERT(0 == uv_run(loop)); |
|
||||
|
|
||||
/* This is somewhat inexact but the idea is that the event loop should not
|
|
||||
* start busy looping when the server sends a message and the client isn't |
|
||||
* reading. |
|
||||
*/ |
|
||||
ASSERT(ticks <= 10); |
|
||||
|
|
||||
return 0; |
|
||||
} |
|
Loading…
Reference in new issue