1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00
2002-12-13  Ulrich Drepper  <drepper@redhat.com>

	* misc/syslog.c (log_cleanup): Don't use parameter in
	__libc_lock_unlock call, use syslog_lock directly.  Adjust callers to
	pass NULL instead of a pointer to syslog_lock.
This commit is contained in:
Ulrich Drepper
2002-12-13 10:59:14 +00:00
parent b9633fccd3
commit 9ae0909b35
22 changed files with 312 additions and 77 deletions

View File

@ -1,3 +1,9 @@
2002-12-13 Ulrich Drepper <drepper@redhat.com>
* misc/syslog.c (log_cleanup): Don't use parameter in
__libc_lock_unlock call, use syslog_lock directly. Adjust callers to
pass NULL instead of a pointer to syslog_lock.
2002-12-12 Ulrich Drepper <drepper@redhat.com> 2002-12-12 Ulrich Drepper <drepper@redhat.com>
* iconvdata/Makefile: iconv-rules: Add definition to use gconv.map * iconvdata/Makefile: iconv-rules: Add definition to use gconv.map

View File

@ -333,7 +333,7 @@ openlog_internal(const char *ident, int logstat, int logfac)
static void static void
log_cleanup (void *arg) log_cleanup (void *arg)
{ {
__libc_lock_unlock (*(__libc_lock_t *) arg); __libc_lock_unlock (syslog_lock);
} }
void void
@ -341,7 +341,7 @@ openlog (const char *ident, int logstat, int logfac)
{ {
#ifdef _LIBC_REENTRANT #ifdef _LIBC_REENTRANT
/* Protect against multiple users. */ /* Protect against multiple users. */
__libc_cleanup_region_start (1, log_cleanup, &syslog_lock); __libc_cleanup_region_start (1, log_cleanup, NULL);
__libc_lock_lock (syslog_lock); __libc_lock_lock (syslog_lock);
#endif #endif
@ -375,7 +375,7 @@ closelog ()
{ {
#ifdef _LIBC_REENTRANT #ifdef _LIBC_REENTRANT
/* Protect against multiple users. */ /* Protect against multiple users. */
__libc_cleanup_region_start (1, log_cleanup, &syslog_lock); __libc_cleanup_region_start (1, log_cleanup, NULL);
__libc_lock_lock (syslog_lock); __libc_lock_lock (syslog_lock);
#endif #endif

View File

@ -1,3 +1,38 @@
2002-12-13 Ulrich Drepper <drepper@redhat.com>
* Makefile (routines): Add libc-cancellation.
* libc-cancellation.c: New file.
* descr.h (struct pthread): Add multiple_threads field.
* allocatestack.c (allocate_stack): Initialize multiple_header field of
new thread descriptor to 1.
* sysdeps/unix/sysv/linux/i386/createthread.c (create_thread):
Initialize multiple_thread field after successful thread creation.
* cancellation.c (__do_cancel): Move to pthreadP.h.
(__pthread_enable_asynccancel): Remove parameter from __do_cancel call.
(__pthread_disable_asynccancel): Add internal_function attribute.
* init.c (sigcancel_handler): Remove parameter from __do_cancel call.
* pthread_setcancelstate.c: Likewise.
* pthread_setcanceltype.c: Likewise.
* pthread_exit.c: Likewise.
* pthreadP.h (CANCELLATION_P): Likewise.
(__do_cancel): Define as static inline.
(LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): New #defines.
(__libc_enable_asynccancel, __libc_disable_asynccancel): New
declarations.
* sysdeps/i386/tls.h (tcbhead_t): Add list and multiple_threads
fields. Define MULTIPLE_THREADS_OFFSET.
* sysdeps/pthread/bits/libc-lock.h: Remove __libc_locking_needed
declaration.
* sysdeps/unix/sysv/linux/accept.S: New file.
* sysdeps/unix/sysv/linux/read.c: New file.
* sysdeps/unix/sysv/linux/write.c: New file.
* sysdeps/unix/sysv/linux/i386/pt-socket.S: New file.
* sysdeps/unix/sysv/linux/libc_pthread_init.c: Remove definition and
initialization of __libc_locking_needed.
* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Don't use
__libc_locking_needed, use multiple_threads field in TCB.
* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
2002-12-12 Ulrich Drepper <drepper@redhat.com> 2002-12-12 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: Use i486 * sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: Use i486

View File

@ -28,7 +28,7 @@ headers := pthread.h semaphore.h
extra-libs := libpthread extra-libs := libpthread
extra-libs-others := $(extra-libs) extra-libs-others := $(extra-libs)
routines = alloca_cutoff forward libc-lowlevellock routines = alloca_cutoff forward libc-lowlevellock libc-cancellation
shared-only-routines = forward shared-only-routines = forward
libpthread-routines = init events \ libpthread-routines = init events \

View File

@ -272,6 +272,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* This is a user-provided stack. */ /* This is a user-provided stack. */
pd->user_stack = true; pd->user_stack = true;
/* There is at least one more thread. */
pd->header.data.multiple_threads = 1;
/* Allocate the DTV for this thread. */ /* Allocate the DTV for this thread. */
if (_dl_allocate_tls (pd) == NULL) if (_dl_allocate_tls (pd) == NULL)
/* Something went wrong. */ /* Something went wrong. */
@ -337,6 +340,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
/* Initialize the lock. */ /* Initialize the lock. */
pd->lock = LLL_LOCK_INITIALIZER; pd->lock = LLL_LOCK_INITIALIZER;
/* There is at least one more thread. */
pd->header.data.multiple_threads = 1;
/* Allocate the DTV for this thread. */ /* Allocate the DTV for this thread. */
if (_dl_allocate_tls (pd) == NULL) if (_dl_allocate_tls (pd) == NULL)
{ {

View File

@ -23,35 +23,6 @@
#include "atomic.h" #include "atomic.h"
/* This function is responsible for calling all registered cleanup
handlers and then terminate the thread. This includes dellocating
the thread-specific data. The implementation is complicated by the
fact that we have to handle to cancellation handler registration
methods: exceptions using try/finally and setjmp.
The setjmp method is always available. The user might compile some
code which uses this method because no modern compiler is
available. So we have to handle these first since we cannot call
the cleanup handlers if the stack frames are gone. At the same
time this opens a hole for the register exception handler blocks
since now they might be in danger of using an overwritten stack
frame. The advise is to only use new or only old style cancellation
handling. */
void
__do_cancel (char *currentframe)
{
struct pthread *self = THREAD_SELF;
/* Throw an exception. */
// XXX TBI
/* If throwing an exception didn't work try the longjmp. */
__libc_longjmp (self->cancelbuf, 1);
/* NOTREACHED */
}
/* The next two functions are similar to pthread_setcanceltype() but /* The next two functions are similar to pthread_setcanceltype() but
more specialized for the use in the cancelable functions like write(). more specialized for the use in the cancelable functions like write().
They do not need to check parameters etc. */ They do not need to check parameters etc. */
@ -76,7 +47,7 @@ __pthread_enable_asynccancel (void)
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{ {
THREAD_SETMEM (self, result, PTHREAD_CANCELED); THREAD_SETMEM (self, result, PTHREAD_CANCELED);
__do_cancel (CURRENT_STACK_FRAME); __do_cancel ();
} }
break; break;
@ -88,7 +59,7 @@ __pthread_enable_asynccancel (void)
void void
attribute_hidden internal_function attribute_hidden
__pthread_disable_asynccancel (int oldtype) __pthread_disable_asynccancel (int oldtype)
{ {
/* If asynchronous cancellation was enabled before we do not have /* If asynchronous cancellation was enabled before we do not have

View File

@ -58,6 +58,8 @@ struct pthread
/* XXX Remove this union for IA-64 style TLS module */ /* XXX Remove this union for IA-64 style TLS module */
union union
{ {
/* It is very important to always append new elements. The offsets
of some of the elements of the struct are used in assembler code. */
struct struct
{ {
void *tcb; /* Pointer to the TCB. This is not always void *tcb; /* Pointer to the TCB. This is not always
@ -65,6 +67,7 @@ struct pthread
union dtv *dtvp; union dtv *dtvp;
struct pthread *self; /* Pointer to this structure */ struct pthread *self; /* Pointer to this structure */
list_t list; list_t list;
int multiple_threads;
} data; } data;
void *__padding[16]; void *__padding[16];
} header; } header;

View File

@ -84,7 +84,7 @@ sigcancel_handler (int sig __attribute ((unused)))
/* Run the registered destructors and terminate the /* Run the registered destructors and terminate the
thread. */ thread. */
__do_cancel (CURRENT_STACK_FRAME); __do_cancel ();
} }
break; break;

View File

@ -74,7 +74,7 @@ extern int __pthread_debug attribute_hidden;
if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \ if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
{ \ { \
THREAD_SETMEM (self, result, PTHREAD_CANCELED); \ THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
__do_cancel (CURRENT_STACK_FRAME); \ __do_cancel (); \
} \ } \
} while (0) } while (0)
@ -85,9 +85,41 @@ extern int __pthread_debug attribute_hidden;
#define CANCEL_RESET(oldtype) \ #define CANCEL_RESET(oldtype) \
__pthread_disable_asynccancel (oldtype) __pthread_disable_asynccancel (oldtype)
/* Function performing the cancellation. */ /* Same as CANCEL_ASYNC, but for use in libc.so. */
extern void __do_cancel (char *currentframe) #define LIBC_CANCEL_ASYNC() \
__attribute ((visibility ("hidden"), noreturn, regparm (1))); __libc_enable_asynccancel ()
/* Same as CANCEL_RESET, but for use in libc.so. */
#define LIBC_CANCEL_RESET(oldtype) \
__libc_disable_asynccancel (oldtype)
/* This function is responsible for calling all registered cleanup
handlers and then terminate the thread. This includes dellocating
the thread-specific data. The implementation is complicated by the
fact that we have to handle to cancellation handler registration
methods: exceptions using try/finally and setjmp.
The setjmp method is always available. The user might compile some
code which uses this method because no modern compiler is
available. So we have to handle these first since we cannot call
the cleanup handlers if the stack frames are gone. At the same
time this opens a hole for the register exception handler blocks
since now they might be in danger of using an overwritten stack
frame. The advise is to only use new or only old style cancellation
handling. */
static inline void
__do_cancel (void)
{
struct pthread *self = THREAD_SELF;
/* Throw an exception. */
// XXX TBI
/* If throwing an exception didn't work try the longjmp. */
__libc_longjmp (self->cancelbuf, 1);
/* NOTREACHED */
}
/* Test whether stackframe is still active. */ /* Test whether stackframe is still active. */
@ -186,7 +218,13 @@ extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
extern int __pthread_kill (pthread_t threadid, int signo); extern int __pthread_kill (pthread_t threadid, int signo);
extern int __pthread_setcanceltype (int type, int *oldtype); extern int __pthread_setcanceltype (int type, int *oldtype);
extern int __pthread_enable_asynccancel (void) attribute_hidden; extern int __pthread_enable_asynccancel (void) attribute_hidden;
extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden; extern void __pthread_disable_asynccancel (int oldtype)
internal_function attribute_hidden;
/* The two functions are in libc.so and not exported. */
extern int __libc_enable_asynccancel (void) attribute_hidden;
extern void __libc_disable_asynccancel (int oldtype)
internal_function attribute_hidden;
#ifdef IS_IN_libpthread #ifdef IS_IN_libpthread
/* Special versions which use non-exported functions. */ /* Special versions which use non-exported functions. */

View File

@ -27,5 +27,5 @@ pthread_exit (value)
{ {
THREAD_SETMEM (THREAD_SELF, result, value); THREAD_SETMEM (THREAD_SELF, result, value);
__do_cancel (CURRENT_STACK_FRAME); __do_cancel ();
} }

View File

@ -58,7 +58,7 @@ pthread_setcancelstate (state, oldstate)
oldval) == 0) oldval) == 0)
{ {
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
__do_cancel (CURRENT_STACK_FRAME); __do_cancel ();
break; break;
} }

View File

@ -60,7 +60,7 @@ __pthread_setcanceltype (type, oldtype)
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
{ {
THREAD_SETMEM (self, result, PTHREAD_CANCELED); THREAD_SETMEM (self, result, PTHREAD_CANCELED);
__do_cancel (CURRENT_STACK_FRAME); __do_cancel ();
} }
break; break;

View File

@ -24,6 +24,7 @@
# include <stddef.h> # include <stddef.h>
# include <stdint.h> # include <stdint.h>
# include <stdlib.h> # include <stdlib.h>
# include <list.h>
/* Type for the dtv. */ /* Type for the dtv. */
@ -40,6 +41,8 @@ typedef struct
thread descriptor used by libpthread. */ thread descriptor used by libpthread. */
dtv_t *dtv; dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */ void *self; /* Pointer to the thread descriptor. */
list_t list;
int multiple_threads;
} tcbhead_t; } tcbhead_t;
#endif #endif
@ -52,10 +55,13 @@ typedef struct
/* Signal that TLS support is available. */ /* Signal that TLS support is available. */
#define USE_TLS 1 #define USE_TLS 1
/* Alignment requirement for the stack. For IA-32 this is govern by /* Alignment requirement for the stack. For IA-32 this is governed by
the SSE memory functions. */ the SSE memory functions. */
#define STACK_ALIGN 16 #define STACK_ALIGN 16
/* Offset of the MULTIPLE_THREADS element in tcbhead_t. */
#define MULTIPLE_THREADS_OFFSET 20
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
/* Get system call information. */ /* Get system call information. */

View File

@ -25,12 +25,6 @@
#include <stddef.h> #include <stddef.h>
#if defined _LIBC && !defined NOT_IN_libc
/* Nonzero if locking is needed. */
extern int __libc_locking_needed attribute_hidden;
#endif
/* Fortunately Linux now has a mean to do locking which is realtime /* Fortunately Linux now has a mean to do locking which is realtime
safe without the aid of the thread library. We also need no fancy safe without the aid of the thread library. We also need no fancy
options like error checking mutexes etc. We only need simple options like error checking mutexes etc. We only need simple

View File

@ -0,0 +1,4 @@
#define socket accept
#define __socket __libc_accept
#define NARGS 3
#include <pt-socket.S>

View File

@ -82,6 +82,9 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Failed. */ /* Failed. */
return errno; return errno;
/* We now have for sure more than one thread. */
pd->header.data.multiple_threads = 1;
/* Now fill in the information about the new thread in /* Now fill in the information about the new thread in
the newly created thread's data structure. We cannot let the newly created thread's data structure. We cannot let
the new thread do this since we don't know whether it was the new thread do this since we don't know whether it was
@ -142,5 +145,8 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Failed. */ /* Failed. */
return errno; return errno;
/* We now have for sure more than one thread. */
pd->header.data.multiple_threads = 1;
return 0; return 0;
} }

View File

@ -18,6 +18,7 @@
02111-1307 USA. */ 02111-1307 USA. */
#include <sysdep.h> #include <sysdep.h>
#include <tls.h>
.text .text
@ -48,13 +49,7 @@ __lll_lock_wait:
orl $-1, %eax /* Load -1. */ orl $-1, %eax /* Load -1. */
#ifndef UP #ifndef UP
# ifdef PIC cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
call __i686.get_pc_thunk.dx
addl $_GLOBAL_OFFSET_TABLE_, %edx
cmpl $0, __libc_locking_needed@GOTOFF(%edx)
# else
cmpl $0, __libc_locking_needed
# endif
je,pt 0f je,pt 0f
lock lock
0: 0:
@ -83,13 +78,7 @@ lll_unlock_wake_cb:
movl 20(%esp), %ebx movl 20(%esp), %ebx
#ifndef UP #ifndef UP
# ifdef PIC cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
call __i686.get_pc_thunk.dx
addl $_GLOBAL_OFFSET_TABLE_, %edx
cmpl $0, __libc_locking_needed@GOTOFF(%edx)
# else
cmpl $0, __libc_locking_needed
# endif
je,pt 0f je,pt 0f
lock lock
0: 0:

View File

@ -21,6 +21,7 @@
#define _LOWLEVELLOCK_H 1 #define _LOWLEVELLOCK_H 1
#include <time.h> #include <time.h>
#include <sys/param.h>
#include <bits/pthreadtypes.h> #include <bits/pthreadtypes.h>
#ifndef LOCK_INSTR #ifndef LOCK_INSTR
@ -182,26 +183,27 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
the lock prefix when the thread library is not used. the lock prefix when the thread library is not used.
XXX In future we might even want to avoid it on UP machines. */ XXX In future we might even want to avoid it on UP machines. */
# include <tls.h>
/* Nonzero if locking is needed. */ /* Nonzero if locking is needed. */
extern int __libc_locking_needed attribute_hidden; extern int __libc_locking_needed attribute_hidden;
# define lll_trylock(futex) \ # define lll_trylock(futex) \
({ unsigned char ret; \ ({ unsigned char ret; \
__asm __volatile ("cmpl $0, %5\n\t" \ __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
"je,pt 0f\n\t" \ "je,pt 0f\n\t" \
"lock\n" \ "lock\n" \
"0:\tcmpxchgl %2, %1; setne %0" \ "0:\tcmpxchgl %2, %1; setne %0" \
: "=a" (ret), "=m" (futex) \ : "=a" (ret), "=m" (futex) \
: "r" (0), "1" (futex), "0" (1), \ : "r" (0), "1" (futex), "0" (1), \
"m" (__libc_locking_needed) \ "i" (offsetof (tcbhead_t, multiple_threads)) \
: "memory"); \ : "memory"); \
ret; }) ret; })
# define lll_lock(futex) \ # define lll_lock(futex) \
(void) ({ int ignore1, ignore2; \ (void) ({ int ignore1, ignore2; \
__asm __volatile ("cmpl $0, %5\n\t" \ __asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
"je,pt 0f\n\t" \ "je,pt 0f\n\t" \
"lock\n" \ "lock\n" \
"0:\txaddl %0, %2\n\t" \ "0:\txaddl %0, %2\n\t" \
@ -214,13 +216,13 @@ extern int __libc_locking_needed attribute_hidden;
"2:" \ "2:" \
: "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \ : "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \
: "0" (-1), "2" (futex), \ : "0" (-1), "2" (futex), \
"m" (__libc_locking_needed) \ "i" (offsetof (tcbhead_t, multiple_threads)) \
: "memory"); }) : "memory"); })
# define lll_unlock(futex) \ # define lll_unlock(futex) \
(void) ({ int ignore; \ (void) ({ int ignore; \
__asm __volatile ("cmpl $0, %3\n\t" \ __asm __volatile ("cmpl $0, %%gs:%P3\n\t" \
"je,pt 0f\n\t" \ "je,pt 0f\n\t" \
"lock\n" \ "lock\n" \
"0:\tincl %0\n\t" \ "0:\tincl %0\n\t" \
@ -232,7 +234,8 @@ extern int __libc_locking_needed attribute_hidden;
".previous\n" \ ".previous\n" \
"2:" \ "2:" \
: "=m" (futex), "=&a" (ignore) \ : "=m" (futex), "=&a" (ignore) \
: "0" (futex), "m" (__libc_locking_needed) \ : "0" (futex), \
"i" (offsetof (tcbhead_t, multiple_threads)) \
: "memory"); }) : "memory"); })
#endif #endif

View File

@ -0,0 +1,80 @@
/* Copyright (C) 1995, 1996, 1997, 1998, 2002 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 Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <socketcall.h>
#define P(a, b) P2(a, b)
#define P2(a, b) a##b
.text
/* The socket-oriented system calls are handled unusally in Linux.
They are all gated through the single `socketcall' system call number.
`socketcall' takes two arguments: the first is the subcode, specifying
which socket function is being called; and the second is a pointer to
the arguments to the specific function.
The .S files for the other calls just #define socket and #include this. */
#ifndef __socket
# error "__socket and socket must be defined"
#endif
.globl __socket
ENTRY (__socket)
/* We need one more register. */
pushl %esi
/* Enable asynchronous cancellation. */
call __libc_enable_asynccancel /* No @plt */
movl %eax, %esi
/* Save registers. */
movl %ebx, %edx
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
/* Use ## so `socket' is a separate token that might be #define'd. */
movl $P(SOCKOP_,socket), %ebx /* Subcode is first arg to syscall. */
lea 8(%esp), %ecx /* Address of args is 2nd arg. */
/* Do the system call trap. */
int $0x80
/* Restore the cancellation. */
xchgl %esi, %eax
call __libc_disable_asynccancel /* No @plt */
/* Restore registers. */
movl %esi, %eax
movl %edx, %ebx
popl %esi
/* %eax is < 0 if there was an error. */
cmpl $-125, %eax
jae SYSCALL_ERROR_LABEL
/* Successful; return the syscall's value. */
L(pseudo_end):
ret
PSEUDO_END (__socket)
#ifndef NO_WEAK_ALIAS
weak_alias (__socket, socket)
#endif

View File

@ -24,9 +24,6 @@
static struct fork_handler pthread_child_handler; static struct fork_handler pthread_child_handler;
/* Global variable signalled when locking is needed. */
int __libc_locking_needed;
void void
__libc_pthread_init (ptr, reclaim) __libc_pthread_init (ptr, reclaim)
@ -41,7 +38,4 @@ __libc_pthread_init (ptr, reclaim)
/* The fork handler needed by libpthread. */ /* The fork handler needed by libpthread. */
list_add_tail (&pthread_child_handler.list, &__fork_child_list); list_add_tail (&pthread_child_handler.list, &__fork_child_list);
/* Signal the internal locking code that locking is needed now. */
__libc_locking_needed = 1;
} }

View File

@ -0,0 +1,50 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <stdlib.h>
#include <sysdep.h>
#include <unistd.h>
#include <nptl/pthreadP.h>
#include <tls.h>
ssize_t
__libc_read (int fd, void *buf, size_t count)
{
#ifndef NOT_IN_libc
if (__builtin_expect (THREAD_GETMEM (THREAD_SELF,
header.data.multiple_threads) == 0, 1))
return INLINE_SYSCALL (read, 3, fd, buf, count);
int oldtype = LIBC_CANCEL_ASYNC ();
#endif
ssize_t result = INLINE_SYSCALL (read, 3, fd, buf, count);
#ifndef NOT_IN_libc
LIBC_CANCEL_RESET (oldtype);
#endif
return result;
}
libc_hidden_def (__libc_read)
strong_alias (__libc_read, __read)
libc_hidden_weak (__read)
weak_alias (__libc_read, read)

View File

@ -0,0 +1,50 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <stdlib.h>
#include <sysdep.h>
#include <unistd.h>
#include <nptl/pthreadP.h>
#include <tls.h>
ssize_t
__libc_write (int fd, const void *buf, size_t count)
{
#ifndef NOT_IN_libc
if (__builtin_expect (THREAD_GETMEM (THREAD_SELF,
header.data.multiple_threads) == 0, 1))
return INLINE_SYSCALL (write, 3, fd, buf, count);
int oldtype = LIBC_CANCEL_ASYNC ();
#endif
ssize_t result = INLINE_SYSCALL (write, 3, fd, buf, count);
#ifndef NOT_IN_libc
LIBC_CANCEL_RESET (oldtype);
#endif
return result;
}
libc_hidden_def (__libc_write)
strong_alias (__libc_write, __write)
libc_hidden_weak (__write)
weak_alias (__libc_write, write)