OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [newlib-1.18.0/] [newlib/] [libc/] [sys/] [linux/] [linuxthreads/] [ptfork.c] - Blame information for rev 207

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/* Linuxthreads - a simple clone()-based implementation of Posix        */
2
/* threads for Linux.                                                   */
3
/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
4
/*                                                                      */
5
/* This program is free software; you can redistribute it and/or        */
6
/* modify it under the terms of the GNU Library General Public License  */
7
/* as published by the Free Software Foundation; either version 2       */
8
/* of the License, or (at your option) any later version.               */
9
/*                                                                      */
10
/* This program is distributed in the hope that it will be useful,      */
11
/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
12
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
13
/* GNU Library General Public License for more details.                 */
14
 
15
/* The "atfork" stuff */
16
 
17
#include <errno.h>
18
#include <stddef.h>
19
#include <stdlib.h>
20
#include <unistd.h>
21
#include "pthread.h"
22
#include "internals.h"
23
#include <bits/libc-lock.h>
24
 
25
struct handler_list {
26
  void (*handler)(void);
27
  struct handler_list * next;
28
};
29
 
30
static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER;
31
static struct handler_list * pthread_atfork_prepare = NULL;
32
static struct handler_list * pthread_atfork_parent = NULL;
33
static struct handler_list * pthread_atfork_child = NULL;
34
 
35
static void pthread_insert_list(struct handler_list ** list,
36
                                void (*handler)(void),
37
                                struct handler_list * newlist,
38
                                int at_end)
39
{
40
  if (handler == NULL) return;
41
  if (at_end) {
42
    while(*list != NULL) list = &((*list)->next);
43
  }
44
  newlist->handler = handler;
45
  newlist->next = *list;
46
  *list = newlist;
47
}
48
 
49
struct handler_list_block {
50
  struct handler_list prepare, parent, child;
51
};
52
 
53
int __pthread_atfork(void (*prepare)(void),
54
                     void (*parent)(void),
55
                     void (*child)(void))
56
{
57
  struct handler_list_block * block =
58
    (struct handler_list_block *) malloc(sizeof(struct handler_list_block));
59
  if (block == NULL) return ENOMEM;
60
  pthread_mutex_lock(&pthread_atfork_lock);
61
  /* "prepare" handlers are called in LIFO */
62
  pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0);
63
  /* "parent" handlers are called in FIFO */
64
  pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1);
65
  /* "child" handlers are called in FIFO */
66
  pthread_insert_list(&pthread_atfork_child, child, &block->child, 1);
67
  pthread_mutex_unlock(&pthread_atfork_lock);
68
  return 0;
69
}
70
strong_alias (__pthread_atfork, pthread_atfork)
71
 
72
static inline void pthread_call_handlers(struct handler_list * list)
73
{
74
  for (/*nothing*/; list != NULL; list = list->next) (list->handler)();
75
}
76
 
77
extern int __libc_fork(void);
78
 
79
pid_t __fork(void)
80
{
81
  pid_t pid;
82
 
83
  pthread_mutex_lock(&pthread_atfork_lock);
84
 
85
  pthread_call_handlers(pthread_atfork_prepare);
86
  __pthread_once_fork_prepare();
87
  __flockfilelist();
88
 
89
  pid = __libc_fork();
90
 
91
  if (pid == 0) {
92
    __pthread_reset_main_thread();
93
 
94
    __fresetlockfiles();
95
    __pthread_once_fork_child();
96
    pthread_call_handlers(pthread_atfork_child);
97
 
98
    pthread_mutex_init(&pthread_atfork_lock, NULL);
99
  } else {
100
    __funlockfilelist();
101
    __pthread_once_fork_parent();
102
    pthread_call_handlers(pthread_atfork_parent);
103
 
104
    pthread_mutex_unlock(&pthread_atfork_lock);
105
  }
106
 
107
  return pid;
108
}
109
 
110
weak_alias (__fork, fork);
111
 
112
#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 4
113
 
114
pid_t __vfork(void)
115
{
116
  return __fork();
117
}
118
weak_alias (__vfork, vfork);
119
 
120
#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 4 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.