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:
+33
-19
@@ -1138,8 +1138,8 @@ spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
|
|||||||
// public kernel exported functions
|
// public kernel exported functions
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
|
send_data_etc(thread_id tid, int32 code, const void *buffer, size_t buffer_size, int32 flags)
|
||||||
{
|
{
|
||||||
struct thread *target;
|
struct thread *target;
|
||||||
sem_id cached_sem;
|
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)
|
if (buffer_size > THREAD_MAX_MESSAGE_SIZE)
|
||||||
return B_NO_MEMORY;
|
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)
|
if (rv == B_INTERRUPTED)
|
||||||
// We got interrupted by a signal
|
// We got interrupted by a signal
|
||||||
return rv;
|
return rv;
|
||||||
@@ -1211,35 +1211,49 @@ send_data(thread_id tid, int32 code, const void *buffer, size_t buffer_size)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
status_t status;
|
||||||
size_t size;
|
size_t size;
|
||||||
int32 code;
|
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)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
size = min(bufferSize, t->msg.size);
|
size = min(bufferSize, thread->msg.size);
|
||||||
status = cbuf_user_memcpy_from_chain(buffer, t->msg.buffer, 0, size);
|
status = cbuf_user_memcpy_from_chain(buffer, thread->msg.buffer, 0, size);
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
cbuf_free_chain(t->msg.buffer);
|
cbuf_free_chain(thread->msg.buffer);
|
||||||
release_sem(t->msg.write_sem);
|
release_sem(thread->msg.write_sem);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
*sender = t->msg.sender;
|
*sender = thread->msg.sender;
|
||||||
code = t->msg.code;
|
code = thread->msg.code;
|
||||||
|
|
||||||
cbuf_free_chain(t->msg.buffer);
|
cbuf_free_chain(thread->msg.buffer);
|
||||||
release_sem(t->msg.write_sem);
|
release_sem(thread->msg.write_sem);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
receive_data(thread_id *sender, void *buffer, size_t bufferSize)
|
||||||
|
{
|
||||||
|
return receive_data_etc(sender, buffer, bufferSize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
has_data(thread_id thread)
|
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))
|
if (!IS_USER_ADDRESS(buffer))
|
||||||
return B_BAD_ADDRESS;
|
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
|
// supports userland buffers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
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;
|
thread_id sender;
|
||||||
status_t code;
|
status_t code;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userSender)
|
if (!IS_USER_ADDRESS(_userSender)
|
||||||
|| !IS_USER_ADDRESS(buffer))
|
|| !IS_USER_ADDRESS(buffer))
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
code = receive_data(&sender, buffer, bufferSize);
|
code = receive_data_etc(&sender, buffer, bufferSize, B_CAN_INTERRUPT);
|
||||||
// supports userland buffers
|
// 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 B_BAD_ADDRESS;
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|||||||
Reference in New Issue
Block a user