Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace undocumented APIs with documented APIs in the OpenJDK #22

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 50 additions & 50 deletions src/java.base/windows/native/libnio/ch/wepoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ enum EPOLL_EVENTS {
EPOLLWRBAND = (int) (1U << 9),
EPOLLMSG = (int) (1U << 10), /* Never reported. */
EPOLLRDHUP = (int) (1U << 13),
EPOLLONESHOT = (int) (1U << 31)
EPOLLONESHOT = (int) (1U << 30)
};

#define EPOLLIN (1U << 0)
Expand All @@ -91,7 +91,7 @@ enum EPOLL_EVENTS {
#define EPOLLWRBAND (1U << 9)
#define EPOLLMSG (1U << 10)
#define EPOLLRDHUP (1U << 13)
#define EPOLLONESHOT (1U << 31)
#define EPOLLONESHOT (1U << 30)

#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_MOD 2
Expand Down Expand Up @@ -227,11 +227,6 @@ typedef struct _OBJECT_ATTRIBUTES {
#define FILE_OPEN 0x00000001UL
#endif

#define KEYEDEVENT_WAIT 0x00000001UL
#define KEYEDEVENT_WAKE 0x00000002UL
#define KEYEDEVENT_ALL_ACCESS \
(STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)

#define NT_NTDLL_IMPORT_LIST(X) \
X(NTSTATUS, \
NTAPI, \
Expand All @@ -255,14 +250,6 @@ typedef struct _OBJECT_ATTRIBUTES {
PVOID EaBuffer, \
ULONG EaLength)) \
\
X(NTSTATUS, \
NTAPI, \
NtCreateKeyedEvent, \
(PHANDLE KeyedEventHandle, \
ACCESS_MASK DesiredAccess, \
POBJECT_ATTRIBUTES ObjectAttributes, \
ULONG Flags)) \
\
X(NTSTATUS, \
NTAPI, \
NtDeviceIoControlFile, \
Expand All @@ -277,22 +264,6 @@ typedef struct _OBJECT_ATTRIBUTES {
PVOID OutputBuffer, \
ULONG OutputBufferLength)) \
\
X(NTSTATUS, \
NTAPI, \
NtReleaseKeyedEvent, \
(HANDLE KeyedEventHandle, \
PVOID KeyValue, \
BOOLEAN Alertable, \
PLARGE_INTEGER Timeout)) \
\
X(NTSTATUS, \
NTAPI, \
NtWaitForKeyedEvent, \
(HANDLE KeyedEventHandle, \
PVOID KeyValue, \
BOOLEAN Alertable, \
PLARGE_INTEGER Timeout)) \
\
X(ULONG, WINAPI, RtlNtStatusToDosError, (NTSTATUS Status))

#define X(return_type, attributes, name, parameters) \
Expand Down Expand Up @@ -491,7 +462,7 @@ WEPOLL_INTERNAL port_state_t* port_state_from_handle_tree_node(
WEPOLL_INTERNAL ts_tree_node_t* port_state_to_handle_tree_node(
port_state_t* port_state);

/* The reflock is a special kind of lock that normally prevents a chunk of
/* A reflock is a special kind of lock that normally prevents a chunk of
* memory from being freed, but does allow the chunk of memory to eventually be
* released in a coordinated fashion.
*
Expand All @@ -504,13 +475,15 @@ WEPOLL_INTERNAL ts_tree_node_t* port_state_to_handle_tree_node(
* "destroy" returns, the calling thread may assume that no other threads have
* a reference to the lock.
*
* Attemmpting to lock or destroy a lock after reflock_unref_and_destroy() has
* Attempting to lock or destroy a lock after reflock_unref_and_destroy() has
* been called is invalid and results in undefined behavior. Therefore the user
* should use another lock to guarantee that this can't happen.
*/

typedef struct reflock {
volatile long state; /* 32-bit Interlocked APIs operate on `long` values. */
CONDITION_VARIABLE cv_signal;
CONDITION_VARIABLE cv_await;
} reflock_t;

WEPOLL_INTERNAL int reflock_global_init(void);
Expand Down Expand Up @@ -1550,35 +1523,60 @@ bool queue_is_enqueued(const queue_node_t* node) {
#define REFLOCK__REF ((long) 0x00000001UL)
#define REFLOCK__REF_MASK ((long) 0x0fffffffUL)
#define REFLOCK__DESTROY ((long) 0x10000000UL)
#define REFLOCK__DESTROY_MASK ((long) 0xf0000000UL)
#define REFLOCK__POISON ((long) 0x300dead0UL)
#define REFLOCK__DESTROY_MASK ((long) 0x10000000UL)
#define REFLOCK__SIGNAL ((long) 0x20000000UL)
#define REFLOCK__SIGNAL_MASK ((long) 0x20000000UL)
#define REFLOCK__AWAIT ((long) 0x40000000UL)
#define REFLOCK__AWAIT_MASK ((long) 0x40000000UL)
#define REFLOCK__POISON ((long) 0x800dead0UL)

static HANDLE reflock__keyed_event = NULL;
static CRITICAL_SECTION signalMutex;

int reflock_global_init(void) {
NTSTATUS status = NtCreateKeyedEvent(
&reflock__keyed_event, KEYEDEVENT_ALL_ACCESS, NULL, 0);
if (status != STATUS_SUCCESS)
return_set_error(-1, RtlNtStatusToDosError(status));
InitializeCriticalSection(&signalMutex);
return 0;
}

void reflock_init(reflock_t* reflock) {
reflock->state = 0;
InitializeConditionVariable(&reflock->cv_signal);
InitializeConditionVariable(&reflock->cv_await);
}

static void reflock__signal_event(void* address) {
NTSTATUS status =
NtReleaseKeyedEvent(reflock__keyed_event, address, FALSE, NULL);
if (status != STATUS_SUCCESS)
static void reflock__signal_event(reflock_t* reflock) {
BOOL status = TRUE;

EnterCriticalSection(&signalMutex);
long state = InterlockedOr(&reflock->state, REFLOCK__SIGNAL);
while ((reflock->state & REFLOCK__AWAIT_MASK) == 0) {
status = SleepConditionVariableCS(&reflock->cv_signal, &signalMutex, INFINITE);
}
LeaveCriticalSection(&signalMutex);

if (status != TRUE)
abort();

/* At most one reflock__await_event call per reflock. */
WakeConditionVariable(&reflock->cv_await);
unused_var(state);
}

static void reflock__await_event(void* address) {
NTSTATUS status =
NtWaitForKeyedEvent(reflock__keyed_event, address, FALSE, NULL);
if (status != STATUS_SUCCESS)
static void reflock__await_event(reflock_t* reflock) {
BOOL status = TRUE;

EnterCriticalSection(&signalMutex);
long state = InterlockedOr(&reflock->state, REFLOCK__AWAIT);
while ((reflock->state & REFLOCK__SIGNAL_MASK) == 0) {
status = SleepConditionVariableCS(&reflock->cv_await, &signalMutex, INFINITE);
}
LeaveCriticalSection(&signalMutex);

if (status != TRUE)
abort();

/* Multiple threads could be waiting. */
WakeAllConditionVariable(&reflock->cv_signal);
unused_var(state);
}

void reflock_ref(reflock_t* reflock) {
Expand All @@ -1595,7 +1593,8 @@ void reflock_unref(reflock_t* reflock) {
/* Verify that the lock was referenced and not already destroyed. */
assert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0);

if (state == REFLOCK__DESTROY)
if ((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY &&
(state & REFLOCK__REF_MASK) == 0)
reflock__signal_event(reflock);
}

Expand All @@ -1611,7 +1610,8 @@ void reflock_unref_and_destroy(reflock_t* reflock) {
reflock__await_event(reflock);

state = InterlockedExchange(&reflock->state, REFLOCK__POISON);
assert(state == REFLOCK__DESTROY);
assert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY);
assert((state & REFLOCK__REF_MASK) == 0);
}

#define SOCK__KNOWN_EPOLL_EVENTS \
Expand Down
4 changes: 2 additions & 2 deletions src/java.base/windows/native/libnio/ch/wepoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ enum EPOLL_EVENTS {
EPOLLWRBAND = (int) (1U << 9),
EPOLLMSG = (int) (1U << 10), /* Never reported. */
EPOLLRDHUP = (int) (1U << 13),
EPOLLONESHOT = (int) (1U << 31)
EPOLLONESHOT = (int) (1U << 30)
};

#define EPOLLIN (1U << 0)
Expand All @@ -94,7 +94,7 @@ enum EPOLL_EVENTS {
#define EPOLLWRBAND (1U << 9)
#define EPOLLMSG (1U << 10)
#define EPOLLRDHUP (1U << 13)
#define EPOLLONESHOT (1U << 31)
#define EPOLLONESHOT (1U << 30)

#define EPOLL_CTL_ADD 1
#define EPOLL_CTL_MOD 2
Expand Down