source: trunk/src/gcc/libobjc/thr.c@ 80

Last change on this file since 80 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 14.2 KB
RevLine 
[2]1/* GNU Objective C Runtime Thread Interface
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Galen C. Hunt ([email protected])
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 2, or (at your option) any later version.
10
11GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14details.
15
16You should have received a copy of the GNU General Public License along with
17GNU CC; see the file COPYING. If not, write to the Free Software
18Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21/* As a special exception, if you link this library with files compiled with
22 GCC to produce an executable, this does not cause the resulting executable
23 to be covered by the GNU General Public License. This exception does not
24 however invalidate any other reasons why the executable file might be
25 covered by the GNU General Public License. */
26
27#include <stdlib.h>
28#include "runtime.h"
29
30/* Global exit status. */
31int __objc_thread_exit_status = 0;
32
33/* Flag which lets us know if we ever became multi threaded */
34int __objc_is_multi_threaded = 0;
35
36/* The hook function called when the runtime becomes multi threaded */
37objc_thread_callback _objc_became_multi_threaded = NULL;
38
39/*
40 Use this to set the hook function that will be called when the
41 runtime initially becomes multi threaded.
42 The hook function is only called once, meaning only when the
43 2nd thread is spawned, not for each and every thread.
44
45 It returns the previous hook function or NULL if there is none.
46
47 A program outside of the runtime could set this to some function so
48 it can be informed; for example, the GNUstep Base Library sets it
49 so it can implement the NSBecomingMultiThreaded notification.
50 */
51objc_thread_callback objc_set_thread_callback(objc_thread_callback func)
52{
53 objc_thread_callback temp = _objc_became_multi_threaded;
54 _objc_became_multi_threaded = func;
55 return temp;
56}
57
58/*
59 Private functions
60
61 These functions are utilized by the frontend, but they are not
62 considered part of the public interface.
63 */
64
65/*
66 First function called in a thread, starts everything else.
67
68 This function is passed to the backend by objc_thread_detach
69 as the starting function for a new thread.
70 */
71struct __objc_thread_start_state
72{
73 SEL selector;
74 id object;
75 id argument;
76};
77
78static volatile void
79__objc_thread_detach_function(struct __objc_thread_start_state *istate)
80{
81 /* Valid state? */
82 if (istate) {
83 id (*imp)(id,SEL,id);
84 SEL selector = istate->selector;
85 id object = istate->object;
86 id argument = istate->argument;
87
88 /* Don't need anymore so free it */
89 objc_free(istate);
90
91 /* Clear out the thread local storage */
92 objc_thread_set_data(NULL);
93
94 /* Check to see if we just became multi threaded */
95 if (!__objc_is_multi_threaded)
96 {
97 __objc_is_multi_threaded = 1;
98
99 /* Call the hook function */
100 if (_objc_became_multi_threaded != NULL)
101 (*_objc_became_multi_threaded)();
102 }
103
104 /* Call the method */
105 if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector)))
106 (*imp)(object, selector, argument);
107 else
108 objc_error(object, OBJC_ERR_UNIMPLEMENTED,
109 "objc_thread_detach called with bad selector.\n");
110 }
111 else
112 objc_error(nil, OBJC_ERR_BAD_STATE,
113 "objc_thread_detach called with NULL state.\n");
114
115 /* Exit the thread */
116 objc_thread_exit();
117}
118
119/*
120 Frontend functions
121
122 These functions constitute the public interface to the Objective-C thread
123 and mutex functionality.
124 */
125
126/* Frontend thread functions */
127
128/*
129 Detach a new thread of execution and return its id. Returns NULL if fails.
130 Thread is started by sending message with selector to object. Message
131 takes a single argument.
132 */
133objc_thread_t
134objc_thread_detach(SEL selector, id object, id argument)
135{
136 struct __objc_thread_start_state *istate;
137 objc_thread_t thread_id = NULL;
138
139 /* Allocate the state structure */
140 if (!(istate = (struct __objc_thread_start_state *)
141 objc_malloc(sizeof(*istate))))
142 return NULL;
143
144 /* Initialize the state structure */
145 istate->selector = selector;
146 istate->object = object;
147 istate->argument = argument;
148
149 /* lock access */
150 objc_mutex_lock(__objc_runtime_mutex);
151
152 /* Call the backend to spawn the thread */
153 if ((thread_id = __objc_thread_detach((void *)__objc_thread_detach_function,
154 istate)) == NULL)