On second thought, it would be strange if the pattern used everywhere

else is not found here. The BeOS kernel also exports these two *_etc()
functions, and we might want to do that, too.
{receive|send}_data() are now interruptible from userland, but not when
called from the kernel.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6700 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-02-23 06:29:59 +00:00
parent ac526351a8
commit f9e9fb76f0

View File

@ -1138,8 +1138,8 @@ spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
// public kernel exported functions
status_t
send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
static status_t
send_data_etc(thread_id tid, int32 code, const void *buffer, size_t buffer_size, int32 flags)
{
struct thread *target;
sem_id cached_sem;
@ -1162,7 +1162,7 @@ send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
if (buffer_size > THREAD_MAX_MESSAGE_SIZE)
return B_NO_MEMORY;
rv = acquire_sem_etc(cached_sem, 1, B_CAN_INTERRUPT, 0);
rv = acquire_sem_etc(cached_sem, 1, flags, 0);
if (rv == B_INTERRUPTED)
// We got interrupted by a signal
return rv;
@ -1211,35 +1211,49 @@ send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
status_t
receive_data(thread_id *sender, void *buffer, size_t bufferSize)
send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
{
struct thread *t = thread_get_current_thread();
return send_data_etc(thread, code, buffer, bufferSize, 0);
}
static status_t
receive_data_etc(thread_id *sender, void *buffer, size_t bufferSize, int32 flags)
{
struct thread *thread = thread_get_current_thread();
status_t status;
size_t size;
int32 code;
status = acquire_sem_etc(t->msg.read_sem, 1, B_CAN_INTERRUPT, 0);
status = acquire_sem_etc(thread->msg.read_sem, 1, flags, 0);
if (status < B_OK)
return status;
size = min(bufferSize, t->msg.size);
status = cbuf_user_memcpy_from_chain(buffer, t->msg.buffer, 0, size);
size = min(bufferSize, thread->msg.size);
status = cbuf_user_memcpy_from_chain(buffer, thread->msg.buffer, 0, size);
if (status < B_OK) {
cbuf_free_chain(t->msg.buffer);
release_sem(t->msg.write_sem);
cbuf_free_chain(thread->msg.buffer);
release_sem(thread->msg.write_sem);
return status;
}
*sender = t->msg.sender;
code = t->msg.code;
*sender = thread->msg.sender;
code = thread->msg.code;
cbuf_free_chain(t->msg.buffer);
release_sem(t->msg.write_sem);
cbuf_free_chain(thread->msg.buffer);
release_sem(thread->msg.write_sem);
return code;
}
status_t
receive_data(thread_id *sender, void *buffer, size_t bufferSize)
{
return receive_data_etc(sender, buffer, bufferSize, 0);
}
bool
has_data(thread_id thread)
{
@ -1668,25 +1682,25 @@ user_send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSi
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
return send_data(thread, code, buffer, bufferSize);
return send_data_etc(thread, code, buffer, bufferSize, B_CAN_INTERRUPT);
// supports userland buffers
}
status_t
user_receive_data(thread_id *userSender, void *buffer, size_t bufferSize)
user_receive_data(thread_id *_userSender, void *buffer, size_t bufferSize)
{
thread_id sender;
status_t code;
if (!IS_USER_ADDRESS(userSender)
if (!IS_USER_ADDRESS(_userSender)
|| !IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
code = receive_data(&sender, buffer, bufferSize);
code = receive_data_etc(&sender, buffer, bufferSize, B_CAN_INTERRUPT);
// supports userland buffers
if (user_memcpy(userSender, &sender, sizeof(thread_id)) < B_OK)
if (user_memcpy(_userSender, &sender, sizeof(thread_id)) < B_OK)
return B_BAD_ADDRESS;
return code;