Added (kernel private) B_PEEK_PORT_MESSAGE flag for read_port_etc().
When specified, the message is read but not removed from the port. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27527 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
68e6763b07
commit
b4ec7b8ee5
@ -15,6 +15,14 @@ struct select_info;
|
||||
|
||||
#define PORT_FLAG_USE_USER_MEMCPY 0x80000000
|
||||
|
||||
// port flags
|
||||
enum {
|
||||
// read_port_etc() flags
|
||||
B_PEEK_PORT_MESSAGE = 0x100 // read the message, but don't remove it;
|
||||
// kernel-only; memory must be locked
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -29,7 +37,8 @@ status_t deselect_port(int32 object, struct select_info *info, bool kernel);
|
||||
|
||||
// currently private API
|
||||
status_t writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
||||
size_t vecCount, size_t bufferSize, uint32 flags, bigtime_t timeout);
|
||||
size_t vecCount, size_t bufferSize, uint32 flags,
|
||||
bigtime_t timeout);
|
||||
|
||||
// temp: test
|
||||
void port_test(void);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <sem.h>
|
||||
#include <syscall_restart.h>
|
||||
#include <team.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/list.h>
|
||||
#include <wait_for_objects.h>
|
||||
|
||||
@ -369,7 +370,7 @@ port_init(kernel_args *args)
|
||||
// #pragma mark - public kernel API
|
||||
|
||||
|
||||
port_id
|
||||
port_id
|
||||
create_port(int32 queueLength, const char *name)
|
||||
{
|
||||
cpu_status state;
|
||||
@ -575,7 +576,7 @@ delete_port(port_id id)
|
||||
|
||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||
|
||||
// update the first free slot hint in the array
|
||||
// update the first free slot hint in the array
|
||||
GRAB_PORT_LIST_LOCK();
|
||||
if (slot < sFirstFreeSlot)
|
||||
sFirstFreeSlot = slot;
|
||||
@ -959,7 +960,8 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize,
|
||||
cpu_status state;
|
||||
sem_id cachedSem;
|
||||
status_t status;
|
||||
bool userCopy = (flags & PORT_FLAG_USE_USER_MEMCPY) > 0;
|
||||
bool userCopy = (flags & PORT_FLAG_USE_USER_MEMCPY) != 0;
|
||||
bool peekOnly = !userCopy && (flags & B_PEEK_PORT_MESSAGE) != 0;
|
||||
port_msg *msg;
|
||||
size_t size;
|
||||
int slot;
|
||||
@ -1024,6 +1026,19 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize,
|
||||
return B_BAD_PORT_ID;
|
||||
}
|
||||
|
||||
if (peekOnly) {
|
||||
size = min_c(bufferSize, msg->size);
|
||||
if (_msgCode != NULL)
|
||||
*_msgCode = msg->code;
|
||||
if (size > 0)
|
||||
cbuf_memcpy_from_chain(msgBuffer, msg->buffer_chain, 0, size);
|
||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||
restore_interrupts(state);
|
||||
release_sem_etc(cachedSem, 1, B_DO_NOT_RESCHEDULE);
|
||||
// we only peeked, but didn't grab the message
|
||||
return size;
|
||||
}
|
||||
|
||||
list_remove_link(msg);
|
||||
|
||||
sPorts[slot].total_count++;
|
||||
@ -1122,7 +1137,7 @@ writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
||||
return B_BAD_PORT_ID;
|
||||
}
|
||||
|
||||
// store sem_id in local variable
|
||||
// store sem_id in local variable
|
||||
cachedSem = sPorts[slot].write_sem;
|
||||
|
||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||
@ -1204,7 +1219,7 @@ writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
||||
|
||||
notify_port_select_events(slot, B_EVENT_READ);
|
||||
|
||||
// store sem_id in local variable
|
||||
// store sem_id in local variable
|
||||
cachedSem = sPorts[slot].read_sem;
|
||||
|
||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||
|
Loading…
Reference in New Issue
Block a user