2007-10-02 19:47:31 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2007, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _KERNEL_WAIT_FOR_OBJECTS_H
|
|
|
|
#define _KERNEL_WAIT_FOR_OBJECTS_H
|
|
|
|
|
|
|
|
#include <OS.h>
|
|
|
|
|
|
|
|
#include <lock.h>
|
|
|
|
|
|
|
|
|
|
|
|
struct select_sync;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct select_info {
|
kernel: Add event queue implementation to wait for objects efficiently.
Based on hamishm's original patch from 2015, but heavily modified,
refactored, and reworked.
From the original commit message:
> When an object is deleted, a B_EVENT_INVALID event is delivered,
> and the object is unregistered from the queue.
>
> The special event flag B_EVENT_ONE_SHOT can be passed in when adding
> an object so that the object is automatically unregistered when an
> event is delivered.
Modifications to the original change include:
* Removed the public interface (syscalls remain private for the moment)
* Event list queueing/dequeueing almost entirely rewritten, including:
- Clear events field when dequeueing.
- Have B_EVENT_QUEUED actually indicate whether the event has been
appended to the linked list (or not), based around lock state.
The previous logic was prone to races and double-insertions.
- "Modify" is now just "Deselect + Select" performed at once;
previously it could cause use-after-frees.
- Unlock for deselect only once at the end of dequeue.
- Handle INVALID events still in the queue upon destruction,
fixing memory leaks.
* Deduplified code with wait_for_objects.
* Use of C++ virtual dispatch instead of C-style enum + function calls,
and BReferenceable plus destructors for teardown.
* Removed select/modify/delete flags. Select/Modify are now the same
operation on the syscall interface, and "Delete" is done when 0
is passed for "events". Additionally, the events selected can be fetched
by passing -1 for "events".
* Implemented level-triggered mode.
* Use of BStackOrHeapArray and other convenience routines in syscalls.
Change-Id: I1d2f094fd981c95215a59adbc087523c7bbbe40b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6745
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
2023-07-26 16:51:38 -04:00
|
|
|
struct select_info* next;
|
|
|
|
struct select_sync* sync;
|
|
|
|
int32 events;
|
|
|
|
uint16 selected_events;
|
2007-10-02 19:47:31 +00:00
|
|
|
} select_info;
|
|
|
|
|
|
|
|
|
|
|
|
#define SELECT_FLAG(type) (1L << (type - 1))
|
|
|
|
|
2018-01-20 23:38:11 +08:00
|
|
|
#define SELECT_OUTPUT_ONLY_FLAGS \
|
|
|
|
(B_EVENT_ERROR | B_EVENT_DISCONNECTED | B_EVENT_INVALID)
|
|
|
|
|
|
|
|
#define SELECT_TYPE_IS_OUTPUT_ONLY(type) \
|
|
|
|
((SELECT_FLAG(type) & SELECT_OUTPUT_ONLY_FLAGS) != 0)
|
|
|
|
|
2007-10-02 19:47:31 +00:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
kernel: Add event queue implementation to wait for objects efficiently.
Based on hamishm's original patch from 2015, but heavily modified,
refactored, and reworked.
From the original commit message:
> When an object is deleted, a B_EVENT_INVALID event is delivered,
> and the object is unregistered from the queue.
>
> The special event flag B_EVENT_ONE_SHOT can be passed in when adding
> an object so that the object is automatically unregistered when an
> event is delivered.
Modifications to the original change include:
* Removed the public interface (syscalls remain private for the moment)
* Event list queueing/dequeueing almost entirely rewritten, including:
- Clear events field when dequeueing.
- Have B_EVENT_QUEUED actually indicate whether the event has been
appended to the linked list (or not), based around lock state.
The previous logic was prone to races and double-insertions.
- "Modify" is now just "Deselect + Select" performed at once;
previously it could cause use-after-frees.
- Unlock for deselect only once at the end of dequeue.
- Handle INVALID events still in the queue upon destruction,
fixing memory leaks.
* Deduplified code with wait_for_objects.
* Use of C++ virtual dispatch instead of C-style enum + function calls,
and BReferenceable plus destructors for teardown.
* Removed select/modify/delete flags. Select/Modify are now the same
operation on the syscall interface, and "Delete" is done when 0
is passed for "events". Additionally, the events selected can be fetched
by passing -1 for "events".
* Implemented level-triggered mode.
* Use of BStackOrHeapArray and other convenience routines in syscalls.
Change-Id: I1d2f094fd981c95215a59adbc087523c7bbbe40b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6745
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
2023-07-26 16:51:38 -04:00
|
|
|
#endif
|
2007-10-02 19:47:31 +00:00
|
|
|
|
|
|
|
|
kernel: Add event queue implementation to wait for objects efficiently.
Based on hamishm's original patch from 2015, but heavily modified,
refactored, and reworked.
From the original commit message:
> When an object is deleted, a B_EVENT_INVALID event is delivered,
> and the object is unregistered from the queue.
>
> The special event flag B_EVENT_ONE_SHOT can be passed in when adding
> an object so that the object is automatically unregistered when an
> event is delivered.
Modifications to the original change include:
* Removed the public interface (syscalls remain private for the moment)
* Event list queueing/dequeueing almost entirely rewritten, including:
- Clear events field when dequeueing.
- Have B_EVENT_QUEUED actually indicate whether the event has been
appended to the linked list (or not), based around lock state.
The previous logic was prone to races and double-insertions.
- "Modify" is now just "Deselect + Select" performed at once;
previously it could cause use-after-frees.
- Unlock for deselect only once at the end of dequeue.
- Handle INVALID events still in the queue upon destruction,
fixing memory leaks.
* Deduplified code with wait_for_objects.
* Use of C++ virtual dispatch instead of C-style enum + function calls,
and BReferenceable plus destructors for teardown.
* Removed select/modify/delete flags. Select/Modify are now the same
operation on the syscall interface, and "Delete" is done when 0
is passed for "events". Additionally, the events selected can be fetched
by passing -1 for "events".
* Implemented level-triggered mode.
* Use of BStackOrHeapArray and other convenience routines in syscalls.
Change-Id: I1d2f094fd981c95215a59adbc087523c7bbbe40b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6745
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
2023-07-26 16:51:38 -04:00
|
|
|
extern void acquire_select_sync(select_sync* sync);
|
2007-10-02 19:47:31 +00:00
|
|
|
extern void put_select_sync(select_sync* sync);
|
|
|
|
extern status_t notify_select_events(select_info* info, uint16 events);
|
|
|
|
extern void notify_select_events_list(select_info* list, uint16 events);
|
|
|
|
|
|
|
|
extern ssize_t _user_wait_for_objects(object_wait_info* userInfos,
|
|
|
|
int numInfos, uint32 flags, bigtime_t timeout);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif // _KERNEL_WAIT_FOR_OBJECTS_H
|