mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
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:
@ -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>
|
||||
|
||||
* iconvdata/Makefile: iconv-rules: Add definition to use gconv.map
|
||||
|
@ -333,7 +333,7 @@ openlog_internal(const char *ident, int logstat, int logfac)
|
||||
static void
|
||||
log_cleanup (void *arg)
|
||||
{
|
||||
__libc_lock_unlock (*(__libc_lock_t *) arg);
|
||||
__libc_lock_unlock (syslog_lock);
|
||||
}
|
||||
|
||||
void
|
||||
@ -341,7 +341,7 @@ openlog (const char *ident, int logstat, int logfac)
|
||||
{
|
||||
#ifdef _LIBC_REENTRANT
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
@ -375,7 +375,7 @@ closelog ()
|
||||
{
|
||||
#ifdef _LIBC_REENTRANT
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
|
@ -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>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: Use i486
|
||||
|
@ -28,7 +28,7 @@ headers := pthread.h semaphore.h
|
||||
extra-libs := libpthread
|
||||
extra-libs-others := $(extra-libs)
|
||||
|
||||
routines = alloca_cutoff forward libc-lowlevellock
|
||||
routines = alloca_cutoff forward libc-lowlevellock libc-cancellation
|
||||
shared-only-routines = forward
|
||||
|
||||
libpthread-routines = init events \
|
||||
|
@ -272,6 +272,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
/* This is a user-provided stack. */
|
||||
pd->user_stack = true;
|
||||
|
||||
/* There is at least one more thread. */
|
||||
pd->header.data.multiple_threads = 1;
|
||||
|
||||
/* Allocate the DTV for this thread. */
|
||||
if (_dl_allocate_tls (pd) == NULL)
|
||||
/* Something went wrong. */
|
||||
@ -337,6 +340,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
/* Initialize the lock. */
|
||||
pd->lock = LLL_LOCK_INITIALIZER;
|
||||
|
||||
/* There is at least one more thread. */
|
||||
pd->header.data.multiple_threads = 1;
|
||||
|
||||
/* Allocate the DTV for this thread. */
|
||||
if (_dl_allocate_tls (pd) == NULL)
|
||||
{
|
||||
|
@ -23,35 +23,6 @@
|
||||
#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
|
||||
more specialized for the use in the cancelable functions like write().
|
||||
They do not need to check parameters etc. */
|
||||
@ -76,7 +47,7 @@ __pthread_enable_asynccancel (void)
|
||||
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
||||
{
|
||||
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||
__do_cancel (CURRENT_STACK_FRAME);
|
||||
__do_cancel ();
|
||||
}
|
||||
|
||||
break;
|
||||
@ -88,7 +59,7 @@ __pthread_enable_asynccancel (void)
|
||||
|
||||
|
||||
void
|
||||
attribute_hidden
|
||||
internal_function attribute_hidden
|
||||
__pthread_disable_asynccancel (int oldtype)
|
||||
{
|
||||
/* If asynchronous cancellation was enabled before we do not have
|
||||
|
@ -58,6 +58,8 @@ struct pthread
|
||||
/* XXX Remove this union for IA-64 style TLS module */
|
||||
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
|
||||
{
|
||||
void *tcb; /* Pointer to the TCB. This is not always
|
||||
@ -65,6 +67,7 @@ struct pthread
|
||||
union dtv *dtvp;
|
||||
struct pthread *self; /* Pointer to this structure */
|
||||
list_t list;
|
||||
int multiple_threads;
|
||||
} data;
|
||||
void *__padding[16];
|
||||
} header;
|
||||
|
@ -84,7 +84,7 @@ sigcancel_handler (int sig __attribute ((unused)))
|
||||
|
||||
/* Run the registered destructors and terminate the
|
||||
thread. */
|
||||
__do_cancel (CURRENT_STACK_FRAME);
|
||||
__do_cancel ();
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -74,7 +74,7 @@ extern int __pthread_debug attribute_hidden;
|
||||
if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
|
||||
{ \
|
||||
THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
|
||||
__do_cancel (CURRENT_STACK_FRAME); \
|
||||
__do_cancel (); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@ -85,9 +85,41 @@ extern int __pthread_debug attribute_hidden;
|
||||
#define CANCEL_RESET(oldtype) \
|
||||
__pthread_disable_asynccancel (oldtype)
|
||||
|
||||
/* Function performing the cancellation. */
|
||||
extern void __do_cancel (char *currentframe)
|
||||
__attribute ((visibility ("hidden"), noreturn, regparm (1)));
|
||||
/* Same as CANCEL_ASYNC, but for use in libc.so. */
|
||||
#define LIBC_CANCEL_ASYNC() \
|
||||
__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. */
|
||||
@ -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_setcanceltype (int type, int *oldtype);
|
||||
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
|
||||
/* Special versions which use non-exported functions. */
|
||||
|
@ -27,5 +27,5 @@ pthread_exit (value)
|
||||
{
|
||||
THREAD_SETMEM (THREAD_SELF, result, value);
|
||||
|
||||
__do_cancel (CURRENT_STACK_FRAME);
|
||||
__do_cancel ();
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ pthread_setcancelstate (state, oldstate)
|
||||
oldval) == 0)
|
||||
{
|
||||
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
||||
__do_cancel (CURRENT_STACK_FRAME);
|
||||
__do_cancel ();
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ __pthread_setcanceltype (type, oldtype)
|
||||
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
||||
{
|
||||
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||
__do_cancel (CURRENT_STACK_FRAME);
|
||||
__do_cancel ();
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -24,6 +24,7 @@
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <stdlib.h>
|
||||
# include <list.h>
|
||||
|
||||
|
||||
/* Type for the dtv. */
|
||||
@ -40,6 +41,8 @@ typedef struct
|
||||
thread descriptor used by libpthread. */
|
||||
dtv_t *dtv;
|
||||
void *self; /* Pointer to the thread descriptor. */
|
||||
list_t list;
|
||||
int multiple_threads;
|
||||
} tcbhead_t;
|
||||
#endif
|
||||
|
||||
@ -52,10 +55,13 @@ typedef struct
|
||||
/* Signal that TLS support is available. */
|
||||
#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. */
|
||||
#define STACK_ALIGN 16
|
||||
|
||||
/* Offset of the MULTIPLE_THREADS element in tcbhead_t. */
|
||||
#define MULTIPLE_THREADS_OFFSET 20
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/* Get system call information. */
|
||||
|
@ -25,12 +25,6 @@
|
||||
#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
|
||||
safe without the aid of the thread library. We also need no fancy
|
||||
options like error checking mutexes etc. We only need simple
|
||||
|
4
nptl/sysdeps/unix/sysv/linux/accept.S
Normal file
4
nptl/sysdeps/unix/sysv/linux/accept.S
Normal file
@ -0,0 +1,4 @@
|
||||
#define socket accept
|
||||
#define __socket __libc_accept
|
||||
#define NARGS 3
|
||||
#include <pt-socket.S>
|
@ -82,6 +82,9 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
|
||||
/* Failed. */
|
||||
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
|
||||
the newly created thread's data structure. We cannot let
|
||||
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. */
|
||||
return errno;
|
||||
|
||||
/* We now have for sure more than one thread. */
|
||||
pd->header.data.multiple_threads = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
|
||||
.text
|
||||
|
||||
@ -48,13 +49,7 @@ __lll_lock_wait:
|
||||
|
||||
orl $-1, %eax /* Load -1. */
|
||||
#ifndef UP
|
||||
# ifdef PIC
|
||||
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
|
||||
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
|
||||
je,pt 0f
|
||||
lock
|
||||
0:
|
||||
@ -83,13 +78,7 @@ lll_unlock_wake_cb:
|
||||
|
||||
movl 20(%esp), %ebx
|
||||
#ifndef UP
|
||||
# ifdef PIC
|
||||
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
|
||||
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
|
||||
je,pt 0f
|
||||
lock
|
||||
0:
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define _LOWLEVELLOCK_H 1
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/param.h>
|
||||
#include <bits/pthreadtypes.h>
|
||||
|
||||
#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.
|
||||
|
||||
XXX In future we might even want to avoid it on UP machines. */
|
||||
# include <tls.h>
|
||||
|
||||
/* Nonzero if locking is needed. */
|
||||
extern int __libc_locking_needed attribute_hidden;
|
||||
|
||||
# define lll_trylock(futex) \
|
||||
({ unsigned char ret; \
|
||||
__asm __volatile ("cmpl $0, %5\n\t" \
|
||||
__asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
|
||||
"je,pt 0f\n\t" \
|
||||
"lock\n" \
|
||||
"0:\tcmpxchgl %2, %1; setne %0" \
|
||||
: "=a" (ret), "=m" (futex) \
|
||||
: "r" (0), "1" (futex), "0" (1), \
|
||||
"m" (__libc_locking_needed) \
|
||||
"i" (offsetof (tcbhead_t, multiple_threads)) \
|
||||
: "memory"); \
|
||||
ret; })
|
||||
|
||||
|
||||
# define lll_lock(futex) \
|
||||
(void) ({ int ignore1, ignore2; \
|
||||
__asm __volatile ("cmpl $0, %5\n\t" \
|
||||
__asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
|
||||
"je,pt 0f\n\t" \
|
||||
"lock\n" \
|
||||
"0:\txaddl %0, %2\n\t" \
|
||||
@ -214,13 +216,13 @@ extern int __libc_locking_needed attribute_hidden;
|
||||
"2:" \
|
||||
: "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \
|
||||
: "0" (-1), "2" (futex), \
|
||||
"m" (__libc_locking_needed) \
|
||||
"i" (offsetof (tcbhead_t, multiple_threads)) \
|
||||
: "memory"); })
|
||||
|
||||
|
||||
# define lll_unlock(futex) \
|
||||
(void) ({ int ignore; \
|
||||
__asm __volatile ("cmpl $0, %3\n\t" \
|
||||
__asm __volatile ("cmpl $0, %%gs:%P3\n\t" \
|
||||
"je,pt 0f\n\t" \
|
||||
"lock\n" \
|
||||
"0:\tincl %0\n\t" \
|
||||
@ -232,7 +234,8 @@ extern int __libc_locking_needed attribute_hidden;
|
||||
".previous\n" \
|
||||
"2:" \
|
||||
: "=m" (futex), "=&a" (ignore) \
|
||||
: "0" (futex), "m" (__libc_locking_needed) \
|
||||
: "0" (futex), \
|
||||
"i" (offsetof (tcbhead_t, multiple_threads)) \
|
||||
: "memory"); })
|
||||
#endif
|
||||
|
||||
|
80
nptl/sysdeps/unix/sysv/linux/i386/pt-socket.S
Normal file
80
nptl/sysdeps/unix/sysv/linux/i386/pt-socket.S
Normal 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
|
@ -24,9 +24,6 @@
|
||||
|
||||
static struct fork_handler pthread_child_handler;
|
||||
|
||||
/* Global variable signalled when locking is needed. */
|
||||
int __libc_locking_needed;
|
||||
|
||||
|
||||
void
|
||||
__libc_pthread_init (ptr, reclaim)
|
||||
@ -41,7 +38,4 @@ __libc_pthread_init (ptr, reclaim)
|
||||
|
||||
/* The fork handler needed by libpthread. */
|
||||
list_add_tail (&pthread_child_handler.list, &__fork_child_list);
|
||||
|
||||
/* Signal the internal locking code that locking is needed now. */
|
||||
__libc_locking_needed = 1;
|
||||
}
|
||||
|
50
nptl/sysdeps/unix/sysv/linux/read.c
Normal file
50
nptl/sysdeps/unix/sysv/linux/read.c
Normal 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)
|
50
nptl/sysdeps/unix/sysv/linux/write.c
Normal file
50
nptl/sysdeps/unix/sysv/linux/write.c
Normal 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)
|
Reference in New Issue
Block a user