vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / os / thread.c
blob41e105e4c5f319d37f700300ab61fd7d88d200fb
1 /*
2 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <OS.h>
9 #include <stdlib.h>
10 #include <stdio.h>
12 #include <libroot_private.h>
13 #include <pthread_private.h>
14 #include <runtime_loader.h>
15 #include <thread_defs.h>
16 #include <tls.h>
17 #include <syscalls.h>
20 #undef thread_entry
21 // thread_entry is still defined in OS.h for compatibility reasons
24 typedef struct callback_node {
25 struct callback_node *next;
26 void (*function)(void *);
27 void *argument;
28 } callback_node;
31 void _thread_do_exit_work(void);
32 void _thread_do_exit_notification(void);
35 static status_t
36 thread_entry(void* _entry, void* _thread)
38 thread_func entry = (thread_func)_entry;
39 pthread_thread* thread = (pthread_thread*)_thread;
40 status_t returnCode;
42 returnCode = entry(thread->entry_argument);
44 _thread_do_exit_work();
46 return returnCode;
50 void
51 _thread_do_exit_notification(void)
53 // empty stub for R5 compatibility
57 void
58 _thread_do_exit_work(void)
60 callback_node *node = tls_get(TLS_ON_EXIT_THREAD_SLOT);
61 callback_node *next;
63 while (node != NULL) {
64 next = node->next;
66 node->function(node->argument);
67 free(node);
69 node = next;
72 tls_set(TLS_ON_EXIT_THREAD_SLOT, NULL);
74 __gRuntimeLoader->destroy_thread_tls();
76 __pthread_destroy_thread();
80 void
81 __set_stack_protection(void)
83 if (__gABIVersion < B_HAIKU_ABI_GCC_2_HAIKU) {
84 area_info info;
85 ssize_t cookie = 0;
87 while (get_next_area_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
88 if ((info.protection & B_STACK_AREA) != 0) {
89 _kern_set_area_protection(info.area,
90 B_READ_AREA | B_WRITE_AREA | B_EXECUTE_AREA | B_STACK_AREA);
97 // #pragma mark -
100 thread_id
101 spawn_thread(thread_func entry, const char *name, int32 priority, void *data)
103 struct thread_creation_attributes attributes;
104 pthread_thread* thread;
105 thread_id id;
107 thread = __allocate_pthread(NULL, data);
108 if (thread == NULL)
109 return B_NO_MEMORY;
111 _single_threaded = false;
112 // used for I/O locking - BeOS compatibility issue
114 __pthread_init_creation_attributes(NULL, thread, &thread_entry, entry,
115 thread, name, &attributes);
116 thread->flags |= THREAD_DETACHED;
118 attributes.priority = priority;
120 id = _kern_spawn_thread(&attributes);
121 if (id < 0)
122 free(thread);
123 else {
124 thread->id = id;
125 __set_stack_protection();
128 return id;
132 status_t
133 kill_thread(thread_id thread)
135 return _kern_kill_thread(thread);
139 status_t
140 resume_thread(thread_id thread)
142 return _kern_resume_thread(thread);
146 status_t
147 suspend_thread(thread_id thread)
149 return _kern_suspend_thread(thread);
153 status_t
154 rename_thread(thread_id thread, const char *name)
156 return _kern_rename_thread(thread, name);
160 status_t
161 set_thread_priority(thread_id thread, int32 priority)
163 return _kern_set_thread_priority(thread, priority);
167 void
168 exit_thread(status_t status)
170 _thread_do_exit_work();
171 _kern_exit_thread(status);
175 status_t
176 wait_for_thread(thread_id thread, status_t *_returnCode)
178 return _kern_wait_for_thread(thread, _returnCode);
182 status_t
183 on_exit_thread(void (*callback)(void *), void *data)
185 callback_node **head = (callback_node **)tls_address(TLS_ON_EXIT_THREAD_SLOT);
187 callback_node *node = malloc(sizeof(callback_node));
188 if (node == NULL)
189 return B_NO_MEMORY;
191 node->function = callback;
192 node->argument = data;
194 // add this node to the list
195 node->next = *head;
196 *head = node;
198 return B_OK;
202 status_t
203 _get_thread_info(thread_id thread, thread_info *info, size_t size)
205 if (info == NULL || size != sizeof(thread_info))
206 return B_BAD_VALUE;
208 return _kern_get_thread_info(thread, info);
212 status_t
213 _get_next_thread_info(team_id team, int32 *cookie, thread_info *info, size_t size)
215 if (info == NULL || size != sizeof(thread_info))
216 return B_BAD_VALUE;
218 return _kern_get_next_thread_info(team, cookie, info);
222 status_t
223 send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
225 return _kern_send_data(thread, code, buffer, bufferSize);
229 int32
230 receive_data(thread_id *_sender, void *buffer, size_t bufferSize)
232 return _kern_receive_data(_sender, buffer, bufferSize);
236 bool
237 has_data(thread_id thread)
239 return _kern_has_data(thread);
243 status_t
244 snooze_etc(bigtime_t timeout, int timeBase, uint32 flags)
246 return _kern_snooze_etc(timeout, timeBase, flags, NULL);
250 status_t
251 snooze(bigtime_t timeout)
253 return _kern_snooze_etc(timeout, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT,
254 NULL);
258 status_t
259 snooze_until(bigtime_t timeout, int timeBase)
261 return _kern_snooze_etc(timeout, timeBase, B_ABSOLUTE_TIMEOUT, NULL);