Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1906 serge 1
/*
2
 *  Common routine to implement atexit-like functionality.
3
 */
4
 
5
#include 
6
#include 
7
#include 
8
#include 
9
#include "atexit.h"
10
 
11
/* Make this a weak reference to avoid pulling in malloc.  */
12
void * malloc(size_t) _ATTRIBUTE((__weak__));
13
__LOCK_INIT_RECURSIVE(, __atexit_lock);
14
 
15
/*
16
 * Register a function to be performed at exit or on shared library unload.
17
 */
18
 
19
int
20
_DEFUN (__register_exitproc,
21
	(type, fn, arg, d),
22
	int type _AND
23
	void (*fn) (void) _AND
24
	void *arg _AND
25
	void *d)
26
{
27
  struct _on_exit_args * args;
28
  register struct _atexit *p;
29
 
30
#ifndef __SINGLE_THREAD__
31
  __lock_acquire_recursive(__atexit_lock);
32
#endif
33
 
34
  p = _GLOBAL_REENT->_atexit;
35
  if (p == NULL)
36
    _GLOBAL_REENT->_atexit = p = &_GLOBAL_REENT->_atexit0;
37
  if (p->_ind >= _ATEXIT_SIZE)
38
    {
39
#ifndef _ATEXIT_DYNAMIC_ALLOC
40
      return -1;
41
#else
42
      /* Don't dynamically allocate the atexit array if malloc is not
43
	 available.  */
44
      if (!malloc)
45
	return -1;
46
 
47
      p = (struct _atexit *) malloc (sizeof *p);
48
      if (p == NULL)
49
	{
50
#ifndef __SINGLE_THREAD__
51
	  __lock_release_recursive(__atexit_lock);
52
#endif
53
	  return -1;
54
	}
55
      p->_ind = 0;
56
      p->_next = _GLOBAL_REENT->_atexit;
57
      _GLOBAL_REENT->_atexit = p;
58
#ifndef _REENT_SMALL
59
      p->_on_exit_args._fntypes = 0;
60
      p->_on_exit_args._is_cxa = 0;
61
#endif
62
#endif
63
    }
64
 
65
  if (type != __et_atexit)
66
    {
67
#ifdef _REENT_SMALL
68
      args = p->_on_exit_args_ptr;
69
      if (args == NULL)
70
	{
71
	  if (malloc)
72
	    args = malloc (sizeof * p->_on_exit_args_ptr);
73
 
74
	  if (args == NULL)
75
	    {
76
#ifndef __SINGLE_THREAD__
77
	      __lock_release(lock);
78
#endif
79
	      return -1;
80
	    }
81
	  args->_fntypes = 0;
82
	  args->_is_cxa = 0;
83
	  p->_on_exit_args_ptr = args;
84
	}
85
#else
86
      args = &p->_on_exit_args;
87
#endif
88
      args->_fnargs[p->_ind] = arg;
89
      args->_fntypes |= (1 << p->_ind);
90
      args->_dso_handle[p->_ind] = d;
91
      if (type == __et_cxa)
92
	args->_is_cxa |= (1 << p->_ind);
93
    }
94
  p->_fns[p->_ind++] = fn;
95
#ifndef __SINGLE_THREAD__
96
  __lock_release_recursive(__atexit_lock);
97
#endif
98
  return 0;
99
}