Skip to content

Commit

Permalink
Replace undocumented APIs with documented APIs in the OpenJDK
Browse files Browse the repository at this point in the history
  • Loading branch information
dhanalla committed Aug 8, 2024
1 parent f92c60e commit fbe5cce
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 52 deletions.
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

0 comments on commit fbe5cce

Please sign in to comment.