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:
@@ -15,6 +15,14 @@ struct select_info;
|
|||||||
|
|
||||||
#define PORT_FLAG_USE_USER_MEMCPY 0x80000000
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -29,7 +37,8 @@ status_t deselect_port(int32 object, struct select_info *info, bool kernel);
|
|||||||
|
|
||||||
// currently private API
|
// currently private API
|
||||||
status_t writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
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
|
// temp: test
|
||||||
void port_test(void);
|
void port_test(void);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <sem.h>
|
#include <sem.h>
|
||||||
#include <syscall_restart.h>
|
#include <syscall_restart.h>
|
||||||
#include <team.h>
|
#include <team.h>
|
||||||
|
#include <util/AutoLock.h>
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <wait_for_objects.h>
|
#include <wait_for_objects.h>
|
||||||
|
|
||||||
@@ -369,7 +370,7 @@ port_init(kernel_args *args)
|
|||||||
// #pragma mark - public kernel API
|
// #pragma mark - public kernel API
|
||||||
|
|
||||||
|
|
||||||
port_id
|
port_id
|
||||||
create_port(int32 queueLength, const char *name)
|
create_port(int32 queueLength, const char *name)
|
||||||
{
|
{
|
||||||
cpu_status state;
|
cpu_status state;
|
||||||
@@ -575,7 +576,7 @@ delete_port(port_id id)
|
|||||||
|
|
||||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
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();
|
GRAB_PORT_LIST_LOCK();
|
||||||
if (slot < sFirstFreeSlot)
|
if (slot < sFirstFreeSlot)
|
||||||
sFirstFreeSlot = slot;
|
sFirstFreeSlot = slot;
|
||||||
@@ -959,7 +960,8 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize,
|
|||||||
cpu_status state;
|
cpu_status state;
|
||||||
sem_id cachedSem;
|
sem_id cachedSem;
|
||||||
status_t status;
|
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;
|
port_msg *msg;
|
||||||
size_t size;
|
size_t size;
|
||||||
int slot;
|
int slot;
|
||||||
@@ -1024,6 +1026,19 @@ read_port_etc(port_id id, int32 *_msgCode, void *msgBuffer, size_t bufferSize,
|
|||||||
return B_BAD_PORT_ID;
|
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);
|
list_remove_link(msg);
|
||||||
|
|
||||||
sPorts[slot].total_count++;
|
sPorts[slot].total_count++;
|
||||||
@@ -1122,7 +1137,7 @@ writev_port_etc(port_id id, int32 msgCode, const iovec *msgVecs,
|
|||||||
return B_BAD_PORT_ID;
|
return B_BAD_PORT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store sem_id in local variable
|
// store sem_id in local variable
|
||||||
cachedSem = sPorts[slot].write_sem;
|
cachedSem = sPorts[slot].write_sem;
|
||||||
|
|
||||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
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);
|
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;
|
cachedSem = sPorts[slot].read_sem;
|
||||||
|
|
||||||
RELEASE_PORT_LOCK(sPorts[slot]);
|
RELEASE_PORT_LOCK(sPorts[slot]);
|
||||||
|
|||||||
Reference in New Issue
Block a user