mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
Update.
* Versions.def: Add libanl definition. * shlig-versions: Add entry for libanl. * resolv/Makefile (distribute): Add gai_misc.h and ga_test.c. (routines): Add gai_sigqueue. (extra-libs): Add libanl. (libanl-routines): New variable. Add rules to build libanl and ga_test. * resolv/Versions [libc] (GLIBC_2.2.3): Add __gai_sigqueue. [libanl]: New library. * resolv/netdb.h: Add definitions for libanl. * resolv/getaddrinfo_a.c: New file. * resolv/gai_cancel.c: New file. * resolv/gai_error.c: New file. * resolv/gai_misc.c: New file. * resolv/gai_misc.h: New file. * resolv/gai_notify.c: New file. * resolv/gai_suspend.c: New file. * resolv/ga_test.c: New file. * sysdeps/generic/gai_sigqueue.c: New file. * sysdeps/unix/sysv/linux/gai_sigqueue.c: New file. * sysdeps/generic/bits/siginfo.h: Allow __need_sigevent_t being defined and provide only that definition. * sysdeps/unix/sysv/linux/alpha/bits/siginfo.h: Likewise. * sysdeps/unix/sysv/linux/bits/siginfo.h: Likewise. * sysdeps/unix/sysv/linux/ia64/bits/siginfo.h: Likewise. * sysdeps/unix/sysv/linux/mips/bits/siginfo.h: Likewise. * sysdeps/unix/sysv/linux/sparc/bits/siginfo.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/bits/siginfo.h: Likewise. * rt/aio_misc.c: Fix typos in comments. * rt/lio_listio.c: Pretty printing. Little optimization in request list handling. * elf/rtld.c: Remove commented out code.
This commit is contained in:
parent
28b20578c9
commit
2ace572170
35
ChangeLog
35
ChangeLog
@ -1,5 +1,40 @@
|
||||
2001-03-03 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Versions.def: Add libanl definition.
|
||||
* shlig-versions: Add entry for libanl.
|
||||
* resolv/Makefile (distribute): Add gai_misc.h and ga_test.c.
|
||||
(routines): Add gai_sigqueue.
|
||||
(extra-libs): Add libanl.
|
||||
(libanl-routines): New variable.
|
||||
Add rules to build libanl and ga_test.
|
||||
* resolv/Versions [libc] (GLIBC_2.2.3): Add __gai_sigqueue.
|
||||
[libanl]: New library.
|
||||
* resolv/netdb.h: Add definitions for libanl.
|
||||
* resolv/getaddrinfo_a.c: New file.
|
||||
* resolv/gai_cancel.c: New file.
|
||||
* resolv/gai_error.c: New file.
|
||||
* resolv/gai_misc.c: New file.
|
||||
* resolv/gai_misc.h: New file.
|
||||
* resolv/gai_notify.c: New file.
|
||||
* resolv/gai_suspend.c: New file.
|
||||
* resolv/ga_test.c: New file.
|
||||
* sysdeps/generic/gai_sigqueue.c: New file.
|
||||
* sysdeps/unix/sysv/linux/gai_sigqueue.c: New file.
|
||||
* sysdeps/generic/bits/siginfo.h: Allow __need_sigevent_t being defined
|
||||
and provide only that definition.
|
||||
* sysdeps/unix/sysv/linux/alpha/bits/siginfo.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/bits/siginfo.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/bits/siginfo.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/bits/siginfo.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/bits/siginfo.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/bits/siginfo.h: Likewise.
|
||||
|
||||
* rt/aio_misc.c: Fix typos in comments.
|
||||
* rt/lio_listio.c: Pretty printing. Little optimization in request
|
||||
list handling.
|
||||
|
||||
* elf/rtld.c: Remove commented out code.
|
||||
|
||||
* sysdeps/unix/sysv/linux/linux_fsinfo.h (SHMFS_SUPER_MAGIC):
|
||||
Update for real 2.4 kernels.
|
||||
|
||||
|
12
NEWS
12
NEWS
@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 2001-2-9
|
||||
GNU C Library NEWS -- history of user-visible changes. 2001-3-3
|
||||
|
||||
Copyright (C) 1992-1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
@ -7,6 +7,16 @@ Please send GNU C library bug reports using the `glibcbug' script to
|
||||
<bugs@gnu.org>. Questions and suggestions should be send to
|
||||
<bug-glibc@gnu.org>.
|
||||
|
||||
Version 2.2.3
|
||||
|
||||
* Intel's IA-64 math library is large integrated. It provides fast and
|
||||
accurate implementatations for most basic and standard math functions
|
||||
in float, double, and long double format.
|
||||
|
||||
* An asynchronous name lookup library was added. The interface is designed
|
||||
after POSIX AIO. The proposal was circulated beforehand to get comments.
|
||||
No negative ones came in. Implemented by Ulrich Drepper.
|
||||
|
||||
Version 2.2.2
|
||||
|
||||
* Lots of headers were cleaned up. Using the tool in the conform/ subdir
|
||||
|
@ -95,3 +95,6 @@ ld {
|
||||
libthread_db {
|
||||
GLIBC_2.1.3
|
||||
}
|
||||
libanl {
|
||||
GLIBC_2.2.3
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* siginfo_t, sigevent and constants. Stub version.
|
||||
Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -17,13 +17,15 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -31,6 +33,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
typedef struct siginfo
|
||||
{
|
||||
@ -173,7 +180,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
@ -251,8 +251,7 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (//__builtin_expect (_dl_debug_statistics, 0))
|
||||
__builtin_expect (_dl_debug_mask & DL_DEBUG_STATISTICS, 0))
|
||||
if (__builtin_expect (_dl_debug_mask & DL_DEBUG_STATISTICS, 0))
|
||||
print_statistics ();
|
||||
|
||||
return *start_addr;
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1994,95,96,97,98,99,2000 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -26,16 +26,16 @@ headers := resolv.h \
|
||||
arpa/nameser.h arpa/nameser_compat.h \
|
||||
sys/bitypes.h
|
||||
distribute := ../conf/portability.h mapv4v6addr.h mapv4v6hostent.h \
|
||||
Banner res_hconf.h res_debug.h README
|
||||
Banner res_hconf.h res_debug.h README gai_misc.h ga_test.c
|
||||
|
||||
routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
|
||||
res_hconf res_libc
|
||||
res_hconf res_libc gai_sigqueue
|
||||
|
||||
tests = tst-aton
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
extra-libs := libresolv libnss_dns
|
||||
extra-libs := libresolv libanl libnss_dns
|
||||
extra-libs-others = $(extra-libs)
|
||||
libresolv-routines := gethnamaddr res_comp res_debug \
|
||||
res_data res_mkquery res_query res_send \
|
||||
@ -43,6 +43,9 @@ libresolv-routines := gethnamaddr res_comp res_debug \
|
||||
ns_parse ns_name ns_netint ns_ttl ns_print \
|
||||
ns_samedomain
|
||||
|
||||
libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \
|
||||
getaddrinfo_a
|
||||
|
||||
subdir-dirs = nss_dns
|
||||
vpath %.c nss_dns
|
||||
|
||||
@ -51,6 +54,10 @@ ifneq ($(build-static-nss),yes)
|
||||
libnss_dns-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
endif
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
tests: $(objpfx)ga_test
|
||||
endif
|
||||
|
||||
include ../Rules
|
||||
|
||||
CPPFLAGS += -Dgethostbyname=res_gethostbyname \
|
||||
@ -69,3 +76,8 @@ $(objpfx)libresolv.so: $(common-objpfx)libc.so
|
||||
|
||||
# The DNS NSS modules needs the resolver.
|
||||
$(objpfx)libnss_dns.so: $(objpfx)libresolv.so $(common-objpfx)libc.so
|
||||
|
||||
# The asynchronous name lookup code needs the thread library.
|
||||
$(objpfx)libanl.so: $(common-objpfx)libc.so $(shared-thread-library)
|
||||
|
||||
$(objpfx)ga_test: $(objpfx)libanl.so $(shared-thread-library)
|
||||
|
@ -22,6 +22,9 @@ libc {
|
||||
# r*
|
||||
__res_state; __res_init; __res_nclose; __res_ninit; _res_hconf;
|
||||
}
|
||||
GLIBC_2.2.3 {
|
||||
__gai_sigqueue;
|
||||
}
|
||||
}
|
||||
|
||||
libresolv {
|
||||
@ -66,3 +69,9 @@ libnss_dns {
|
||||
_nss_dns_getnetbyname_r;
|
||||
}
|
||||
}
|
||||
|
||||
libanl {
|
||||
GLIBC_2.2.3 {
|
||||
getaddrinfo_a; gai_cancel; gai_error; gai_suspend;
|
||||
}
|
||||
}
|
||||
|
99
resolv/ga_test.c
Normal file
99
resolv/ga_test.c
Normal file
@ -0,0 +1,99 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
#define N 10
|
||||
struct gaicb reqmem[N];
|
||||
struct gaicb *req[N];
|
||||
int n;
|
||||
|
||||
for (n = 0; n < N; ++n)
|
||||
{
|
||||
asprintf (&reqmem[n].ar_name, "test%d.test.redhat.com", 140 + n);
|
||||
reqmem[n].ar_service = NULL;
|
||||
reqmem[n].ar_request = NULL;
|
||||
reqmem[n].ar_result = NULL;
|
||||
req[n] = &reqmem[n];
|
||||
}
|
||||
|
||||
if (getaddrinfo_a (GAI_NOWAIT, req, N, NULL) != 0)
|
||||
{
|
||||
puts ("queue call failed");
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
puts ("queue call successful");
|
||||
|
||||
while (1)
|
||||
{
|
||||
int any = 0;
|
||||
|
||||
for (n = 0; n < N; ++n)
|
||||
if (req[n] != NULL && gai_error (req[n]) != EAI_INPROGRESS)
|
||||
{
|
||||
if (gai_error (req[n]) == 0)
|
||||
{
|
||||
struct addrinfo *runp = req[n]->ar_result;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
switch (runp->ai_family)
|
||||
{
|
||||
case PF_INET:
|
||||
{
|
||||
struct sockaddr_in *sinp;
|
||||
|
||||
sinp = (struct sockaddr_in *) runp->ai_addr;
|
||||
printf ("%2d: %s = %s\n", n,
|
||||
req[n]->ar_name, inet_ntoa (sinp->sin_addr));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf ("%2d: family %d\n", n, runp->ai_family);
|
||||
break;
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("error for %d: %s\n", n,
|
||||
gai_strerror (gai_error (req[n])));
|
||||
req[n] = NULL;
|
||||
break;
|
||||
}
|
||||
else if (req[n] != NULL)
|
||||
any = 1;
|
||||
|
||||
if (n == N)
|
||||
{
|
||||
if (any)
|
||||
gai_suspend (req, N, NULL);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__libc_write(1,"got all\n", 8);
|
||||
|
||||
for (n = 0; n < N; ++n)
|
||||
if (gai_error (&reqmem[n]) == 0)
|
||||
{
|
||||
struct addrinfo *runp = reqmem[n].ar_result;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
struct addrinfo *oldp = runp;
|
||||
runp = runp->ai_next;
|
||||
freeaddrinfo (oldp);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
48
resolv/gai_cancel.c
Normal file
48
resolv/gai_cancel.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
|
||||
int
|
||||
gai_cancel (struct gaicb *gaicbp)
|
||||
{
|
||||
int result = 0;
|
||||
int status;
|
||||
|
||||
/* Request the mutex. */
|
||||
pthread_mutex_lock (&__gai_requests_mutex);
|
||||
|
||||
/* Find the request among those queued but not yet running. */
|
||||
status = __gai_remove_request (gaicbp);
|
||||
if (status == 0)
|
||||
result = EAI_CANCELED;
|
||||
else if (status > 0)
|
||||
result = EAI_NOTCANCELED;
|
||||
else
|
||||
result = EAI_ALLDONE;
|
||||
|
||||
/* Release the mutex. */
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
|
||||
return result;
|
||||
}
|
28
resolv/gai_error.c
Normal file
28
resolv/gai_error.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
int
|
||||
gai_error (struct gaicb *req)
|
||||
{
|
||||
return req->__return;
|
||||
}
|
423
resolv/gai_misc.c
Normal file
423
resolv/gai_misc.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
|
||||
|
||||
/* Pool of request list entries. */
|
||||
static struct requestlist **pool;
|
||||
|
||||
/* Number of total and allocated pool entries. */
|
||||
static size_t pool_max_size;
|
||||
static size_t pool_size;
|
||||
|
||||
/* We implement a two dimensional array but allocate each row separately.
|
||||
The macro below determines how many entries should be used per row.
|
||||
It should better be a power of two. */
|
||||
#define ENTRIES_PER_ROW 32
|
||||
|
||||
/* How many rows we allocate at once. */
|
||||
#define ROWS_STEP 8
|
||||
|
||||
/* List of available entries. */
|
||||
static struct requestlist *freelist;
|
||||
|
||||
/* Structure list of all currently processed requests. */
|
||||
static struct requestlist *requests;
|
||||
static struct requestlist *requests_tail;
|
||||
|
||||
/* Number of threads currently running. */
|
||||
static int nthreads;
|
||||
|
||||
/* Number of threads waiting for work to arrive. */
|
||||
static int idle_thread_count;
|
||||
|
||||
|
||||
/* These are the values used for optimization. We will probably
|
||||
create a funcion to set these values. */
|
||||
static struct gaiinit optim =
|
||||
{
|
||||
20, /* int gai_threads; Maximal number of threads. */
|
||||
64, /* int gai_num; Number of expected simultanious requests. */
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/* Since the list is global we need a mutex protecting it. */
|
||||
pthread_mutex_t __gai_requests_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
|
||||
/* When you add a request to the list and there are idle threads present,
|
||||
you signal this condition variable. When a thread finishes work, it waits
|
||||
on this condition variable for a time before it actually exits. */
|
||||
pthread_cond_t __gai_new_request_notification = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
|
||||
/* Functions to handle request list pool. */
|
||||
static struct requestlist *
|
||||
get_elem (void)
|
||||
{
|
||||
struct requestlist *result;
|
||||
|
||||
if (freelist == NULL)
|
||||
{
|
||||
struct requestlist *new_row;
|
||||
int cnt;
|
||||
|
||||
if (pool_size + 1 >= pool_max_size)
|
||||
{
|
||||
size_t new_max_size = pool_max_size + ROWS_STEP;
|
||||
struct requestlist **new_tab;
|
||||
|
||||
new_tab = (struct requestlist **)
|
||||
realloc (pool, new_max_size * sizeof (struct requestlist *));
|
||||
|
||||
if (new_tab == NULL)
|
||||
return NULL;
|
||||
|
||||
pool_max_size = new_max_size;
|
||||
pool = new_tab;
|
||||
}
|
||||
|
||||
/* Allocate the new row. */
|
||||
cnt = pool_size == 0 ? optim.gai_num : ENTRIES_PER_ROW;
|
||||
new_row = (struct requestlist *) calloc (cnt,
|
||||
sizeof (struct requestlist));
|
||||
if (new_row == NULL)
|
||||
return NULL;
|
||||
|
||||
pool[pool_size++] = new_row;
|
||||
|
||||
/* Put all the new entries in the freelist. */
|
||||
do
|
||||
{
|
||||
new_row->next = freelist;
|
||||
freelist = new_row++;
|
||||
}
|
||||
while (--cnt > 0);
|
||||
}
|
||||
|
||||
result = freelist;
|
||||
freelist = freelist->next;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct requestlist *
|
||||
internal_function
|
||||
__gai_find_request (const struct gaicb *gaicbp)
|
||||
{
|
||||
struct requestlist *runp;
|
||||
|
||||
runp = requests;
|
||||
while (runp != NULL)
|
||||
if (runp->gaicbp == gaicbp)
|
||||
return runp;
|
||||
else
|
||||
runp = runp->next;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
internal_function
|
||||
__gai_remove_request (struct gaicb *gaicbp)
|
||||
{
|
||||
struct requestlist *runp;
|
||||
struct requestlist *lastp;
|
||||
|
||||
runp = requests;
|
||||
lastp = NULL;
|
||||
while (runp != NULL)
|
||||
if (runp->gaicbp == gaicbp)
|
||||
break;
|
||||
else
|
||||
{
|
||||
lastp = runp;
|
||||
runp = runp->next;
|
||||
}
|
||||
|
||||
if (runp == NULL)
|
||||
/* Not known. */
|
||||
return -1;
|
||||
if (runp->running != 0)
|
||||
/* Currently handled. */
|
||||
return 1;
|
||||
|
||||
/* Dequeue the request. */
|
||||
if (lastp == NULL)
|
||||
requests = runp->next;
|
||||
else
|
||||
lastp->next = runp->next;
|
||||
if (runp == requests_tail)
|
||||
requests_tail = lastp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* The thread handler. */
|
||||
static void *handle_requests (void *arg);
|
||||
|
||||
|
||||
/* The main function of the async I/O handling. It enqueues requests
|
||||
and if necessary starts and handles threads. */
|
||||
struct requestlist *
|
||||
internal_function
|
||||
__gai_enqueue_request (struct gaicb *gaicbp)
|
||||
{
|
||||
struct requestlist *newp;
|
||||
struct requestlist *lastp;
|
||||
|
||||
/* Get the mutex. */
|
||||
pthread_mutex_lock (&__gai_requests_mutex);
|
||||
|
||||
/* Get a new element for the waiting list. */
|
||||
newp = get_elem ();
|
||||
if (newp == NULL)
|
||||
{
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
__set_errno (EAGAIN);
|
||||
return NULL;
|
||||
}
|
||||
newp->running = 0;
|
||||
newp->gaicbp = gaicbp;
|
||||
newp->waiting = NULL;
|
||||
newp->next = NULL;
|
||||
|
||||
lastp = requests_tail;
|
||||
if (requests_tail == NULL)
|
||||
requests = requests_tail = newp;
|
||||
else
|
||||
{
|
||||
requests_tail->next = newp;
|
||||
requests_tail = newp;
|
||||
}
|
||||
|
||||
gaicbp->__return = EAI_INPROGRESS;
|
||||
|
||||
/* See if we need to and are able to create a thread. */
|
||||
if (nthreads < optim.gai_threads && idle_thread_count == 0)
|
||||
{
|
||||
pthread_t thid;
|
||||
pthread_attr_t attr;
|
||||
|
||||
newp->running = 1;
|
||||
|
||||
/* Make sure the thread is created detached. */
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
/* Now try to start a thread. */
|
||||
if (pthread_create (&thid, &attr, handle_requests, newp) == 0)
|
||||
/* We managed to enqueue the request. All errors which can
|
||||
happen now can be recognized by calls to `gai_error'. */
|
||||
++nthreads;
|
||||
else
|
||||
{
|
||||
if (nthreads == 0)
|
||||
{
|
||||
/* We cannot create a thread in the moment and there is
|
||||
also no thread running. This is a problem. `errno' is
|
||||
set to EAGAIN if this is only a temporary problem. */
|
||||
assert (lastp->next == newp);
|
||||
lastp->next = NULL;
|
||||
requests_tail = lastp;
|
||||
|
||||
newp->next = freelist;
|
||||
freelist = newp;
|
||||
|
||||
newp = NULL;
|
||||
}
|
||||
else
|
||||
/* We are not handling the request after all. */
|
||||
newp->running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enqueue the request in the request queue. */
|
||||
if (newp != NULL)
|
||||
{
|
||||
/* If there is a thread waiting for work, then let it know that we
|
||||
have just given it something to do. */
|
||||
if (idle_thread_count > 0)
|
||||
pthread_cond_signal (&__gai_new_request_notification);
|
||||
}
|
||||
|
||||
/* Release the mutex. */
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
|
||||
return newp;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
handle_requests (void *arg)
|
||||
{
|
||||
struct requestlist *runp = (struct requestlist *) arg;
|
||||
|
||||
do
|
||||
{
|
||||
/* If runp is NULL, then we were created to service the work queue
|
||||
in general, not to handle any particular request. In that case we
|
||||
skip the "do work" stuff on the first pass, and go directly to the
|
||||
"get work off the work queue" part of this loop, which is near the
|
||||
end. */
|
||||
if (runp == NULL)
|
||||
pthread_mutex_lock (&__gai_requests_mutex);
|
||||
else
|
||||
{
|
||||
/* Make the request. */
|
||||
struct gaicb *req = runp->gaicbp;
|
||||
struct requestlist *srchp;
|
||||
struct requestlist *lastp;
|
||||
|
||||
req->__return = getaddrinfo (req->ar_name, req->ar_service,
|
||||
req->ar_request, &req->ar_result);
|
||||
|
||||
/* Get the mutex. */
|
||||
pthread_mutex_lock (&__gai_requests_mutex);
|
||||
|
||||
/* Send the signal to notify about finished processing of the
|
||||
request. */
|
||||
__gai_notify (runp);
|
||||
|
||||
/* Now dequeue the current request. */
|
||||
lastp = NULL;
|
||||
srchp = requests;
|
||||
while (srchp != runp)
|
||||
{
|
||||
lastp = srchp;
|
||||
srchp = srchp->next;
|
||||
}
|
||||
assert (runp->running == 1);
|
||||
|
||||
if (requests_tail == runp)
|
||||
requests_tail = lastp;
|
||||
if (lastp == NULL)
|
||||
requests = requests->next;
|
||||
else
|
||||
lastp->next = runp->next;
|
||||
|
||||
/* Free the old element. */
|
||||
runp->next = freelist;
|
||||
freelist = runp;
|
||||
}
|
||||
|
||||
runp = requests;
|
||||
while (runp != NULL && runp->running != 0)
|
||||
runp = runp->next;
|
||||
|
||||
/* If the runlist is empty, then we sleep for a while, waiting for
|
||||
something to arrive in it. */
|
||||
if (runp == NULL && optim.gai_idle_time >= 0)
|
||||
{
|
||||
struct timeval now;
|
||||
struct timespec wakeup_time;
|
||||
|
||||
++idle_thread_count;
|
||||
gettimeofday (&now, NULL);
|
||||
wakeup_time.tv_sec = now.tv_sec + optim.gai_idle_time;
|
||||
wakeup_time.tv_nsec = now.tv_usec * 1000;
|
||||
if (wakeup_time.tv_nsec > 1000000000)
|
||||
{
|
||||
wakeup_time.tv_nsec -= 1000000000;
|
||||
++wakeup_time.tv_sec;
|
||||
}
|
||||
pthread_cond_timedwait (&__gai_new_request_notification,
|
||||
&__gai_requests_mutex, &wakeup_time);
|
||||
--idle_thread_count;
|
||||
runp = requests;
|
||||
while (runp != NULL && runp->running != 0)
|
||||
runp = runp->next;
|
||||
}
|
||||
|
||||
if (runp == NULL)
|
||||
--nthreads;
|
||||
else
|
||||
{
|
||||
/* Mark the request as being worked on. */
|
||||
assert (runp->running == 0);
|
||||
runp->running = 1;
|
||||
|
||||
/* If we have a request to process, and there's still another in
|
||||
the run list, then we need to either wake up or create a new
|
||||
thread to service the request that is still in the run list. */
|
||||
if (requests != NULL)
|
||||
{
|
||||
/* There are at least two items in the work queue to work on.
|
||||
If there are other idle threads, then we should wake them
|
||||
up for these other work elements; otherwise, we should try
|
||||
to create a new thread. */
|
||||
if (idle_thread_count > 0)
|
||||
pthread_cond_signal (&__gai_new_request_notification);
|
||||
else if (nthreads < optim.gai_threads)
|
||||
{
|
||||
pthread_t thid;
|
||||
pthread_attr_t attr;
|
||||
|
||||
/* Make sure the thread is created detached. */
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
/* Now try to start a thread. If we fail, no big deal,
|
||||
because we know that there is at least one thread (us)
|
||||
that is working on lookup operations. */
|
||||
if (pthread_create (&thid, &attr, handle_requests, NULL)
|
||||
== 0)
|
||||
++nthreads;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the mutex. */
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
}
|
||||
while (runp != NULL);
|
||||
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Free allocated resources. */
|
||||
static void
|
||||
__attribute__ ((unused))
|
||||
free_res (void)
|
||||
{
|
||||
size_t row;
|
||||
|
||||
for (row = 0; row < pool_max_size; ++row)
|
||||
free (pool[row]);
|
||||
|
||||
free (pool);
|
||||
}
|
||||
text_set_element (__libc_subfreeres, free_res);
|
100
resolv/gai_misc.h
Normal file
100
resolv/gai_misc.h
Normal file
@ -0,0 +1,100 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _GAI_MISC_H
|
||||
#define _GAI_MISC_H 1
|
||||
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
/* Used to synchronize. */
|
||||
struct waitlist
|
||||
{
|
||||
struct waitlist *next;
|
||||
|
||||
pthread_cond_t *cond;
|
||||
volatile int *counterp;
|
||||
/* The next field is used in asynchronous `lio_listio' operations. */
|
||||
struct sigevent *sigevp;
|
||||
/* XXX See requestlist, it's used to work around the broken signal
|
||||
handling in Linux. */
|
||||
pid_t caller_pid;
|
||||
};
|
||||
|
||||
|
||||
/* Used to queue requests.. */
|
||||
struct requestlist
|
||||
{
|
||||
int running;
|
||||
|
||||
struct requestlist *next;
|
||||
|
||||
/* Pointer to the actual data. */
|
||||
struct gaicb *gaicbp;
|
||||
|
||||
/* List of waiting processes. */
|
||||
struct waitlist *waiting;
|
||||
};
|
||||
|
||||
/* To customize the implementation one can use the following struct.
|
||||
This implementation follows the one in Irix. */
|
||||
struct gaiinit
|
||||
{
|
||||
int gai_threads; /* Maximal number of threads. */
|
||||
int gai_num; /* Number of expected simultanious requests. */
|
||||
int gai_locks; /* Not used. */
|
||||
int gai_usedba; /* Not used. */
|
||||
int gai_debug; /* Not used. */
|
||||
int gai_numusers; /* Not used. */
|
||||
int gai_idle_time; /* Number of seconds before idle thread
|
||||
terminates. */
|
||||
int gai_reserved;
|
||||
};
|
||||
|
||||
|
||||
/* Lock for global I/O list of requests. */
|
||||
extern pthread_mutex_t __gai_requests_mutex;
|
||||
|
||||
|
||||
/* Enqueue request. */
|
||||
extern struct requestlist *__gai_enqueue_request (struct gaicb *gaicbp)
|
||||
internal_function;
|
||||
|
||||
/* Find request on wait list. */
|
||||
extern struct requestlist *__gai_find_request (const struct gaicb *gaicbp)
|
||||
internal_function;
|
||||
|
||||
/* Remove request from waitlist. */
|
||||
extern int __gai_remove_request (struct gaicb *gaicbp)
|
||||
internal_function;
|
||||
|
||||
/* Notify initiator of request and tell this everybody listening. */
|
||||
extern void __gai_notify (struct requestlist *req)
|
||||
internal_function;
|
||||
|
||||
/* Notify initiator of request. */
|
||||
extern int __gai_notify_only (struct sigevent *sigev, pid_t caller_pid)
|
||||
internal_function;
|
||||
|
||||
/* Send the signal. */
|
||||
extern int __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
|
||||
internal_function;
|
||||
|
||||
#endif /* gai_misc.h */
|
100
resolv/gai_notify.c
Normal file
100
resolv/gai_notify.c
Normal file
@ -0,0 +1,100 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
|
||||
static void *
|
||||
notify_func_wrapper (void *arg)
|
||||
{
|
||||
struct sigevent *sigev = arg;
|
||||
sigev->sigev_notify_function (sigev->sigev_value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
internal_function
|
||||
__gai_notify_only (struct sigevent *sigev, pid_t caller_pid)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
/* Send the signal to notify about finished processing of the request. */
|
||||
if (sigev->sigev_notify == SIGEV_THREAD)
|
||||
{
|
||||
/* We have to start a thread. */
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr, *pattr;
|
||||
|
||||
pattr = (pthread_attr_t *) sigev->sigev_notify_attributes;
|
||||
if (pattr == NULL)
|
||||
{
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
pattr = &attr;
|
||||
}
|
||||
|
||||
if (pthread_create (&tid, pattr, notify_func_wrapper, sigev) < 0)
|
||||
result = -1;
|
||||
}
|
||||
else if (sigev->sigev_notify == SIGEV_SIGNAL)
|
||||
/* We have to send a signal. */
|
||||
if (__gai_sigqueue (sigev->sigev_signo, sigev->sigev_value, caller_pid)
|
||||
< 0)
|
||||
result = -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
internal_function
|
||||
__gai_notify (struct requestlist *req)
|
||||
{
|
||||
struct waitlist *waitlist;
|
||||
|
||||
/* Now also notify possibly waiting threads. */
|
||||
waitlist = req->waiting;
|
||||
while (waitlist != NULL)
|
||||
{
|
||||
struct waitlist *next = waitlist->next;
|
||||
|
||||
/* Decrement the counter. This is used in both cases. */
|
||||
--*waitlist->counterp;
|
||||
|
||||
if (waitlist->sigevp == NULL)
|
||||
pthread_cond_signal (waitlist->cond);
|
||||
else
|
||||
/* This is part of a asynchronous `getaddrinfo_a' operation. If
|
||||
this request is the last one, send the signal. */
|
||||
if (*waitlist->counterp == 0)
|
||||
{
|
||||
__gai_notify_only (waitlist->sigevp, waitlist->caller_pid);
|
||||
/* This is tricky. See getaddrinfo_a.c for the reason why
|
||||
this works. */
|
||||
free ((void *) waitlist->counterp);
|
||||
}
|
||||
|
||||
waitlist = next;
|
||||
}
|
||||
}
|
147
resolv/gai_suspend.c
Normal file
147
resolv/gai_suspend.c
Normal file
@ -0,0 +1,147 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
|
||||
int
|
||||
gai_suspend (const struct gaicb *const list[], int ent,
|
||||
const struct timespec *timeout)
|
||||
{
|
||||
struct waitlist waitlist[ent];
|
||||
struct requestlist *requestlist[ent];
|
||||
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
int cnt;
|
||||
int dummy;
|
||||
int none = 1;
|
||||
int result;
|
||||
|
||||
/* Request the mutex. */
|
||||
pthread_mutex_lock (&__gai_requests_mutex);
|
||||
|
||||
/* There is not yet a finished request. Signal the request that
|
||||
we are working for it. */
|
||||
for (cnt = 0; cnt < ent; ++cnt)
|
||||
if (list[cnt] != NULL && list[cnt]->__return == EAI_INPROGRESS)
|
||||
{
|
||||
requestlist[cnt] = __gai_find_request (list[cnt]);
|
||||
|
||||
if (requestlist[cnt] != NULL)
|
||||
{
|
||||
waitlist[cnt].cond = &cond;
|
||||
waitlist[cnt].next = requestlist[cnt]->waiting;
|
||||
waitlist[cnt].counterp = &dummy;
|
||||
waitlist[cnt].sigevp = NULL;
|
||||
waitlist[cnt].caller_pid = 0; /* Not needed. */
|
||||
requestlist[cnt]->waiting = &waitlist[cnt];
|
||||
none = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (none)
|
||||
{
|
||||
if (cnt < ent)
|
||||
/* There is an entry which is finished. */
|
||||
result = 0;
|
||||
else
|
||||
result = EAI_ALLDONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is no request done but some are still being worked on. */
|
||||
int oldstate;
|
||||
|
||||
/* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
|
||||
points we must be careful. We added entries to the waiting lists
|
||||
which we must remove. So defer cancelation for now. */
|
||||
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
|
||||
|
||||
if (timeout == NULL)
|
||||
result = pthread_cond_wait (&cond, &__gai_requests_mutex);
|
||||
else
|
||||
{
|
||||
/* We have to convert the relative timeout value into an
|
||||
absolute time value with pthread_cond_timedwait expects. */
|
||||
struct timeval now;
|
||||
struct timespec abstime;
|
||||
|
||||
__gettimeofday (&now, NULL);
|
||||
abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
|
||||
abstime.tv_sec = timeout->tv_sec + now.tv_sec;
|
||||
if (abstime.tv_nsec >= 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec += 1;
|
||||
}
|
||||
|
||||
result = pthread_cond_timedwait (&cond, &__gai_requests_mutex,
|
||||
&abstime);
|
||||
}
|
||||
|
||||
/* Now remove the entry in the waiting list for all requests
|
||||
which didn't terminate. */
|
||||
for (cnt = 0; cnt < ent; ++cnt)
|
||||
if (list[cnt] != NULL && list[cnt]->__return == EAI_INPROGRESS
|
||||
&& requestlist[cnt] != NULL)
|
||||
{
|
||||
struct waitlist **listp = &requestlist[cnt]->waiting;
|
||||
|
||||
/* There is the chance that we cannot find our entry anymore.
|
||||
This could happen if the request terminated and restarted
|
||||
again. */
|
||||
while (*listp != NULL && *listp != &waitlist[cnt])
|
||||
listp = &(*listp)->next;
|
||||
|
||||
if (*listp != NULL)
|
||||
*listp = (*listp)->next;
|
||||
}
|
||||
|
||||
/* Now it's time to restore the cancelation state. */
|
||||
pthread_setcancelstate (oldstate, NULL);
|
||||
|
||||
/* Release the conditional variable. */
|
||||
if (pthread_cond_destroy (&cond) != 0)
|
||||
/* This must never happen. */
|
||||
abort ();
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
/* An error occurred. Possibly it's EINTR. We have to translate
|
||||
the timeout error report of `pthread_cond_timedwait' to the
|
||||
form expected from `gai_suspend'. */
|
||||
if (__builtin_expect (result, ETIMEDOUT) == ETIMEDOUT)
|
||||
result = EAI_AGAIN;
|
||||
else if (result == EINTR)
|
||||
result = EAI_INTR;
|
||||
else
|
||||
result = EAI_SYSTEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the mutex. */
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
|
||||
return result;
|
||||
}
|
168
resolv/getaddrinfo_a.c
Normal file
168
resolv/getaddrinfo_a.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
|
||||
/* We need this special structure to handle asynchronous I/O. */
|
||||
struct async_waitlist
|
||||
{
|
||||
int counter;
|
||||
struct sigevent sigev;
|
||||
struct waitlist list[0];
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
getaddrinfo_a (int mode, struct gaicb *list[], int ent, struct sigevent *sig)
|
||||
{
|
||||
struct sigevent defsigev;
|
||||
struct requestlist *requests[ent];
|
||||
int cnt;
|
||||
volatile int total = 0;
|
||||
int result = 0;
|
||||
|
||||
/* Check arguments. */
|
||||
if (mode != GAI_WAIT && mode != GAI_NOWAIT)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
|
||||
if (sig == NULL)
|
||||
{
|
||||
defsigev.sigev_notify = SIGEV_NONE;
|
||||
sig = &defsigev;
|
||||
}
|
||||
|
||||
/* Request the mutex. */
|
||||
pthread_mutex_lock (&__gai_requests_mutex);
|
||||
|
||||
/* Now we can enqueue all requests. Since we already acquired the
|
||||
mutex the enqueue function need not do this. */
|
||||
for (cnt = 0; cnt < ent; ++cnt)
|
||||
if (list[cnt] != NULL)
|
||||
{
|
||||
requests[cnt] = __gai_enqueue_request (list[cnt]);
|
||||
|
||||
if (requests[cnt] != NULL)
|
||||
/* Successfully enqueued. */
|
||||
++total;
|
||||
else
|
||||
/* Signal that we've seen an error. `errno' and the error code
|
||||
of the gaicb will tell more. */
|
||||
result = EAI_SYSTEM;
|
||||
}
|
||||
else
|
||||
requests[cnt] = NULL;
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
/* We don't have anything to do except signalling if we work
|
||||
asynchronously. */
|
||||
|
||||
/* Release the mutex. We do this before raising a signal since the
|
||||
signal handler might do a `siglongjmp' and then the mutex is
|
||||
locked forever. */
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
|
||||
if (mode == GAI_NOWAIT)
|
||||
__gai_notify_only (sig,
|
||||
sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
else if (mode == GAI_WAIT)
|
||||
{
|
||||
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
struct waitlist waitlist[ent];
|
||||
int oldstate;
|
||||
|
||||
total = 0;
|
||||
for (cnt = 0; cnt < ent; ++cnt)
|
||||
if (requests[cnt] != NULL)
|
||||
{
|
||||
waitlist[cnt].cond = &cond;
|
||||
waitlist[cnt].next = requests[cnt]->waiting;
|
||||
waitlist[cnt].counterp = &total;
|
||||
waitlist[cnt].sigevp = NULL;
|
||||
waitlist[cnt].caller_pid = 0; /* Not needed. */
|
||||
requests[cnt]->waiting = &waitlist[cnt];
|
||||
++total;
|
||||
}
|
||||
|
||||
/* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
|
||||
points we must be careful. We added entries to the waiting lists
|
||||
which we must remove. So defer cancelation for now. */
|
||||
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
|
||||
|
||||
while (total > 0)
|
||||
pthread_cond_wait (&cond, &__gai_requests_mutex);
|
||||
|
||||
/* Now it's time to restore the cancelation state. */
|
||||
pthread_setcancelstate (oldstate, NULL);
|
||||
|
||||
/* Release the conditional variable. */
|
||||
if (pthread_cond_destroy (&cond) != 0)
|
||||
/* This must never happen. */
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
struct async_waitlist *waitlist;
|
||||
|
||||
waitlist = (struct async_waitlist *)
|
||||
malloc (sizeof (struct async_waitlist)
|
||||
+ (ent * sizeof (struct waitlist)));
|
||||
|
||||
if (waitlist == NULL)
|
||||
result = EAI_AGAIN;
|
||||
else
|
||||
{
|
||||
pid_t caller_pid = sig->sigev_notify == SIGEV_SIGNAL ? getpid () : 0;
|
||||
total = 0;
|
||||
|
||||
for (cnt = 0; cnt < ent; ++cnt)
|
||||
if (requests[cnt] != NULL)
|
||||
{
|
||||
waitlist->list[cnt].cond = NULL;
|
||||
waitlist->list[cnt].next = requests[cnt]->waiting;
|
||||
waitlist->list[cnt].counterp = &waitlist->counter;
|
||||
waitlist->list[cnt].sigevp = &waitlist->sigev;
|
||||
waitlist->list[cnt].caller_pid = caller_pid;
|
||||
requests[cnt]->waiting = &waitlist->list[cnt];
|
||||
++total;
|
||||
}
|
||||
|
||||
waitlist->counter = total;
|
||||
waitlist->sigev = *sig;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the mutex. */
|
||||
pthread_mutex_unlock (&__gai_requests_mutex);
|
||||
|
||||
return result;
|
||||
}
|
@ -33,6 +33,11 @@
|
||||
# include <rpc/netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef __USE_GNU
|
||||
# define __need_sigevent_t
|
||||
# include <bits/siginfo.h>
|
||||
#endif
|
||||
|
||||
#include <bits/netdb.h>
|
||||
|
||||
/* Absolute file name for network data base files. */
|
||||
@ -412,23 +417,48 @@ struct addrinfo
|
||||
struct addrinfo *ai_next; /* Pointer to next in list. */
|
||||
};
|
||||
|
||||
# ifdef __USE_GNU
|
||||
/* Structure used as control block for asynchronous lookup. */
|
||||
struct gaicb
|
||||
{
|
||||
const char *ar_name; /* Name to look up. */
|
||||
const char *ar_service; /* Service name. */
|
||||
const struct addrinfo *ar_request; /* Additional request specification. */
|
||||
struct addrinfo *ar_result; /* Pointer to result. */
|
||||
/* The following are internal elements. */
|
||||
int __return;
|
||||
int __unused[5];
|
||||
};
|
||||
|
||||
/* Lookup mode. */
|
||||
# define GAI_WAIT 0
|
||||
# define GAI_NOWAIT 1
|
||||
# endif
|
||||
|
||||
/* Possible values for `ai_flags' field in `addrinfo' structure. */
|
||||
# define AI_PASSIVE 0x0001 /* Socket address is intended for `bind'. */
|
||||
# define AI_CANONNAME 0x0002 /* Request for canonical name. */
|
||||
# define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */
|
||||
|
||||
/* Error values for `getaddrinfo' function. */
|
||||
# define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */
|
||||
# define EAI_NONAME -2 /* NAME or SERVICE is unknown. */
|
||||
# define EAI_AGAIN -3 /* Temporary failure in name resolution. */
|
||||
# define EAI_FAIL -4 /* Non-recoverable failure in name res. */
|
||||
# define EAI_NODATA -5 /* No address associated with NAME. */
|
||||
# define EAI_FAMILY -6 /* `ai_family' not supported. */
|
||||
# define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */
|
||||
# define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */
|
||||
# define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */
|
||||
# define EAI_MEMORY -10 /* Memory allocation failure. */
|
||||
# define EAI_SYSTEM -11 /* System error returned in `errno'. */
|
||||
# define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */
|
||||
# define EAI_NONAME -2 /* NAME or SERVICE is unknown. */
|
||||
# define EAI_AGAIN -3 /* Temporary failure in name resolution. */
|
||||
# define EAI_FAIL -4 /* Non-recoverable failure in name res. */
|
||||
# define EAI_NODATA -5 /* No address associated with NAME. */
|
||||
# define EAI_FAMILY -6 /* `ai_family' not supported. */
|
||||
# define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */
|
||||
# define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */
|
||||
# define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */
|
||||
# define EAI_MEMORY -10 /* Memory allocation failure. */
|
||||
# define EAI_SYSTEM -11 /* System error returned in `errno'. */
|
||||
# ifdef __USE_GNU
|
||||
# define EAI_INPROGRESS -100 /* Processing request in progress. */
|
||||
# define EAI_CANCELED -101 /* Request canceled. */
|
||||
# define EAI_NOTCANCELED -102 /* Request not canceled. */
|
||||
# define EAI_ALLDONE -103 /* All requests done. */
|
||||
# define EAI_INTR -104 /* Interrupted by a signal. */
|
||||
# endif
|
||||
|
||||
# define NI_MAXHOST 1025
|
||||
# define NI_MAXSERV 32
|
||||
@ -458,6 +488,26 @@ extern int getnameinfo (__const struct sockaddr *__restrict __sa,
|
||||
socklen_t __hostlen, char *__restrict __serv,
|
||||
socklen_t __servlen, unsigned int __flags) __THROW;
|
||||
|
||||
# ifdef __USE_GNU
|
||||
/* Enqueue ENT requests from the LIST. If MODE is GAI_WAIT wait until all
|
||||
requests are handled. If WAIT is GAI_NOWAIT return immediately after
|
||||
queueing the requests and signal completion according to SIG. */
|
||||
extern int getaddrinfo_a (int __mode, struct gaicb *__list[__restrict_arr],
|
||||
int __ent, struct sigevent *__restrict __sig)
|
||||
__THROW;
|
||||
|
||||
/* Suspend execution of the thread until at least one of the ENT requests
|
||||
in LIST is handled. If TIMEOUT is not a null pointer it specifies the
|
||||
longest time the function keeps waiting before returning with an error. */
|
||||
extern int gai_suspend (__const struct gaicb *__const __list[], int __ent,
|
||||
const struct timespec *__timeout) __THROW;
|
||||
|
||||
/* Get the error status of the request REQ. */
|
||||
extern int gai_error (struct gaicb *__req) __THROW;
|
||||
|
||||
/* Cancel the requests associated with GAICBP. */
|
||||
extern int gai_cancel (struct gaicb *__gaicbp) __THROW;
|
||||
# endif /* GNU */
|
||||
#endif /* POSIX */
|
||||
|
||||
__END_DECLS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Handle general operations.
|
||||
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -115,7 +115,7 @@ get_elem (void)
|
||||
pool = new_tab;
|
||||
}
|
||||
|
||||
/* Allocat the new row. */
|
||||
/* Allocate the new row. */
|
||||
cnt = pool_size == 0 ? optim.aio_num : ENTRIES_PER_ROW;
|
||||
new_row = (struct requestlist *) calloc (cnt,
|
||||
sizeof (struct requestlist));
|
||||
@ -414,7 +414,7 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation)
|
||||
++nthreads;
|
||||
else
|
||||
{
|
||||
/* Reset the running flat. The new request is not running. */
|
||||
/* Reset the running flag. The new request is not running. */
|
||||
running = newp->running = yes;
|
||||
|
||||
if (nthreads == 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Enqueue and list of read or write requests.
|
||||
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
@ -70,8 +70,8 @@ lio_listio (mode, list, nent, sig)
|
||||
if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
|
||||
{
|
||||
list[cnt]->aio_sigevent.sigev_notify = SIGEV_NONE;
|
||||
requests[cnt] = __aio_enqueue_request ((aiocb_union *) list[cnt],
|
||||
list[cnt]->aio_lio_opcode);
|
||||
requests[cnt] = __aio_enqueue_request ((aiocb_union *) list[cnt],
|
||||
list[cnt]->aio_lio_opcode);
|
||||
|
||||
if (requests[cnt] != NULL)
|
||||
/* Successfully enqueued. */
|
||||
@ -81,6 +81,8 @@ lio_listio (mode, list, nent, sig)
|
||||
of the aiocb will tell more. */
|
||||
result = -1;
|
||||
}
|
||||
else
|
||||
requests[cnt] = NULL;
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
@ -106,8 +108,7 @@ lio_listio (mode, list, nent, sig)
|
||||
|
||||
total = 0;
|
||||
for (cnt = 0; cnt < nent; ++cnt)
|
||||
if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP
|
||||
&& requests[cnt] != NULL)
|
||||
if (requests[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
|
||||
{
|
||||
waitlist[cnt].cond = &cond;
|
||||
waitlist[cnt].next = requests[cnt]->waiting;
|
||||
@ -153,8 +154,7 @@ lio_listio (mode, list, nent, sig)
|
||||
total = 0;
|
||||
|
||||
for (cnt = 0; cnt < nent; ++cnt)
|
||||
if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP
|
||||
&& requests[cnt] != NULL)
|
||||
if (requests[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
|
||||
{
|
||||
waitlist->list[cnt].cond = NULL;
|
||||
waitlist->list[cnt].next = requests[cnt]->waiting;
|
||||
|
@ -116,3 +116,6 @@ hppa-.*-.* libBrokenLocale=1 GLIBC_2.2
|
||||
# The real-time library from POSIX.1b.
|
||||
mips.*-.*-linux.* librt=1 GLIBC_2.0 GLIBC_2.2
|
||||
.*-.*-.* librt=1
|
||||
|
||||
# The asynchronous name lookup library.
|
||||
.*-.*-.* libanl=1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* siginfo_t, sigevent and constants. Stub version.
|
||||
Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -17,13 +17,15 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -31,6 +33,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
typedef struct siginfo
|
||||
{
|
||||
@ -173,7 +180,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
36
sysdeps/generic/gai_sigqueue.c
Normal file
36
sysdeps/generic/gai_sigqueue.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <aio.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
int
|
||||
__gai_sigqueue (sig, val, caller_pid)
|
||||
int sig;
|
||||
const union sigval val;
|
||||
pid_t caller_pid;
|
||||
{
|
||||
__set_errno (ENOSYS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stub_warning (__gai_sigqueue)
|
||||
#include <stub-tag.h>
|
@ -17,15 +17,17 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -33,6 +35,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if __WORDSIZE == 64
|
||||
@ -246,7 +253,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
@ -17,15 +17,17 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -33,6 +35,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if __WORDSIZE == 64
|
||||
@ -120,7 +127,9 @@ typedef struct siginfo
|
||||
signals. */
|
||||
enum
|
||||
{
|
||||
SI_SIGIO = -5, /* Sent by queued SIGIO. */
|
||||
SI_ASYNCNL = -6, /* Sent by asynch name lookup completion. */
|
||||
# define SI_ASYNCNL SI_ASYNCNL
|
||||
SI_SIGIO, /* Sent by queued SIGIO. */
|
||||
# define SI_SIGIO SI_SIGIO
|
||||
SI_ASYNCIO, /* Sent by AIO completion. */
|
||||
# define SI_ASYNCIO SI_ASYNCIO
|
||||
@ -246,7 +255,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
58
sysdeps/unix/sysv/linux/gai_sigqueue.c
Normal file
58
sysdeps/unix/sysv/linux/gai_sigqueue.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "gai_misc.h"
|
||||
|
||||
#ifdef __NR_rt_sigqueueinfo
|
||||
extern int __syscall_rt_sigqueueinfo (int, int, siginfo_t *__unbounded);
|
||||
|
||||
|
||||
/* Return any pending signal or wait for one for the given time. */
|
||||
int
|
||||
__gai_sigqueue (sig, val, caller_pid)
|
||||
int sig;
|
||||
const union sigval val;
|
||||
pid_t caller_pid;
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
/* First, clear the siginfo_t structure, so that we don't pass our
|
||||
stack content to other tasks. */
|
||||
memset (&info, 0, sizeof (siginfo_t));
|
||||
/* We must pass the information about the data in a siginfo_t value. */
|
||||
info.si_signo = sig;
|
||||
info.si_code = SI_ASYNCNL;
|
||||
info.si_pid = caller_pid;
|
||||
info.si_uid = getuid ();
|
||||
info.si_value = val;
|
||||
|
||||
return INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid,
|
||||
sig, __ptrvalue (&info));
|
||||
}
|
||||
#else
|
||||
# include <sysdeps/generic/gai_sigqueue.c>
|
||||
#endif
|
@ -18,13 +18,15 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigval_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -32,6 +34,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
|
||||
@ -276,7 +283,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
@ -17,13 +17,15 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -31,6 +33,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
|
||||
@ -238,7 +245,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
@ -17,15 +17,17 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -33,6 +35,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if __WORDSIZE == 64
|
||||
@ -255,7 +262,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
@ -17,15 +17,17 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t
|
||||
#if !defined _SIGNAL_H && !defined __need_siginfo_t \
|
||||
&& !defined __need_sigevent_t
|
||||
# error "Never include this file directly. Use <signal.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
#if (!defined __have_sigval_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|
||||
|| defined __need_sigevent_t))
|
||||
# define __have_sigval_t 1
|
||||
|
||||
/* Type for data associated with a signal. */
|
||||
typedef union sigval
|
||||
@ -33,6 +35,11 @@ typedef union sigval
|
||||
int sival_int;
|
||||
void *sival_ptr;
|
||||
} sigval_t;
|
||||
#endif
|
||||
|
||||
#if (!defined __have_siginfo_t \
|
||||
&& (defined _SIGNAL_H || defined __need_siginfo_t))
|
||||
# define __have_siginfo_t 1
|
||||
|
||||
# define __SI_MAX_SIZE 128
|
||||
# if __WORDSIZE == 64
|
||||
@ -246,7 +253,8 @@ enum
|
||||
#endif /* !have siginfo_t && (have _SIGNAL_H || need siginfo_t). */
|
||||
|
||||
|
||||
#if defined _SIGNAL_H && !defined __have_sigevent_t
|
||||
#if (defined _SIGNAL_H || defined __need_sigevent_t) \
|
||||
&& !defined __have_sigevent_t
|
||||
# define __have_sigevent_t 1
|
||||
|
||||
/* Structure to transport application-defined values with signals. */
|
||||
|
Loading…
Reference in New Issue
Block a user