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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libpthread/] [linuxthreads/] [ptfork.c] - Blame information for rev 1771

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

Line No. Rev Author Line
1 1325 phoenix
/* 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
/* mods for uClibc: removed strong alias and defined funcs properly */
16
 
17
/* The "atfork" stuff */
18
 
19
#include <errno.h>
20
#include <stddef.h>
21
#include <stdlib.h>
22
#include <unistd.h>
23
#include "pthread.h"
24
#include "internals.h"
25
 
26
struct handler_list {
27
  void (*handler)(void);
28
  struct handler_list * next;
29
};
30
 
31
static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER;
32
static struct handler_list * pthread_atfork_prepare = NULL;
33
static struct handler_list * pthread_atfork_parent = NULL;
34
static struct handler_list * pthread_atfork_child = NULL;
35
 
36
static void pthread_insert_list(struct handler_list ** list,
37
                                void (*handler)(void),
38
                                struct handler_list * newlist,
39
                                int at_end)
40
{
41
  if (handler == NULL) return;
42
  if (at_end) {
43
    while(*list != NULL) list = &((*list)->next);
44
  }
45
  newlist->handler = handler;
46
  newlist->next = *list;
47
  *list = newlist;
48
}
49
 
50
struct handler_list_block {
51
  struct handler_list prepare, parent, child;
52
};
53
 
54
int pthread_atfork(void (*prepare)(void),
55
                     void (*parent)(void),
56
                     void (*child)(void))
57
{
58
  struct handler_list_block * block =
59
    (struct handler_list_block *) malloc(sizeof(struct handler_list_block));
60
  if (block == NULL) return ENOMEM;
61
  pthread_mutex_lock(&pthread_atfork_lock);
62
  /* "prepare" handlers are called in LIFO */
63
  pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0);
64
  /* "parent" handlers are called in FIFO */
65
  pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1);
66
  /* "child" handlers are called in FIFO */
67
  pthread_insert_list(&pthread_atfork_child, child, &block->child, 1);
68
  pthread_mutex_unlock(&pthread_atfork_lock);
69
  return 0;
70
}
71
//strong_alias (__pthread_atfork, pthread_atfork)
72
 
73
static inline void pthread_call_handlers(struct handler_list * list)
74
{
75
  for (/*nothing*/; list != NULL; list = list->next) (list->handler)();
76
}
77
#ifdef __UCLIBC_HAS_MMU__
78
extern int __libc_fork(void);
79
 
80
pid_t __fork(void)
81
{
82
  pid_t pid;
83
  struct handler_list * prepare, * child, * parent;
84
 
85
  pthread_mutex_lock(&pthread_atfork_lock);
86
  prepare = pthread_atfork_prepare;
87
  child = pthread_atfork_child;
88
  parent = pthread_atfork_parent;
89
  pthread_mutex_unlock(&pthread_atfork_lock);
90
  pthread_call_handlers(prepare);
91
  pid = __libc_fork();
92
  if (pid == 0) {
93
    __pthread_reset_main_thread();
94
    __fresetlockfiles();
95
    pthread_call_handlers(child);
96
  } else {
97
    pthread_call_handlers(parent);
98
  }
99
  return pid;
100
}
101
weak_alias (__fork, fork);
102
 
103
pid_t __vfork(void)
104
{
105
  return __fork();
106
}
107
weak_alias (__vfork, vfork);
108
#else
109
pid_t __vfork(void)
110
{
111
  pid_t pid;
112
  struct handler_list * prepare, * child, * parent;
113
 
114
  pthread_mutex_lock(&pthread_atfork_lock);
115
  prepare = pthread_atfork_prepare;
116
  child = pthread_atfork_child;
117
  parent = pthread_atfork_parent;
118
  pthread_mutex_unlock(&pthread_atfork_lock);
119
  pthread_call_handlers(prepare);
120
  pid = __libc_vfork();
121
  if (pid == 0) {
122
    __pthread_reset_main_thread();
123
    __fresetlockfiles();
124
    pthread_call_handlers(child);
125
  } else {
126
    pthread_call_handlers(parent);
127
  }
128
  return pid;
129
}
130
weak_alias (__vfork, vfork);
131
#endif

powered by: WebSVN 2.1.0

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