Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a0dd202
test(qwp): pin slot retention until worker quiescence
bluestreak01 Jul 10, 2026
8f0dd45
fix(qwp): make engine close a worker-quiescence barrier before releas…
bluestreak01 Jul 10, 2026
d976fd5
fix(qwp): preserve slot ownership after incomplete close
bluestreak01 Jul 10, 2026
d3b6147
test(qwp): pin slot retention on the owned-manager close path
bluestreak01 Jul 10, 2026
7cf9612
perf(qwp): wake quiescence waiters only when one is parked
bluestreak01 Jul 10, 2026
930175f
fix(qwp): transfer slot cleanup to the worker's exit path and recover…
bluestreak01 Jul 10, 2026
eea7f89
test(qwp): pin slot retention when worker-exit handoff registration f…
bluestreak01 Jul 10, 2026
940e130
fix(qwp): publish close completion only after confirmed slot flock re…
bluestreak01 Jul 10, 2026
7b9924c
fix(qwp): retain startup-retired recoverers so a late flock release r…
bluestreak01 Jul 10, 2026
d990470
fix(qwp): give capacity-starved borrows a final retired-slot probe be…
bluestreak01 Jul 10, 2026
7df62d5
test(qwp): close the remaining engine/manager shutdown coverage gaps
bluestreak01 Jul 10, 2026
79e0847
Make final-probe regression deterministic
bluestreak01 Jul 11, 2026
dd0c547
docs(qwp): fix load-bearing concurrency comments that contradict the …
bluestreak01 Jul 11, 2026
b89384f
fix(qwp): recover SF slots after deferred cleanup
bluestreak01 Jul 11, 2026
6b373cb
Merge remote-tracking branch 'origin/fix/qwp-worker-quiescence' into …
bluestreak01 Jul 11, 2026
a086575
fix(qwp): harden cleanup and recovery lifecycle
bluestreak01 Jul 11, 2026
cad1bb8
fix(qwp): make close-time SF cleanup crash-safe and bound flock-relea…
bluestreak01 Jul 11, 2026
a531164
fix(qwp): harden SF crash recovery and cleanup
bluestreak01 Jul 12, 2026
b8d965d
Make socket traffic shutdown idempotent
bluestreak01 Jul 12, 2026
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
27 changes: 27 additions & 0 deletions core/src/main/c/share/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,21 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_fsync
return res;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_fsyncDir0
(JNIEnv *e, jclass cl, jlong lpszName) {
int fd;
RESTARTABLE(open((const char *) (uintptr_t) lpszName, O_RDONLY), fd);
if (fd < 0) {
return -1;
}
int res;
RESTARTABLE(fsync(fd), res);
int saved_errno = errno;
close(fd);
errno = saved_errno;
return res;
}

JNIEXPORT jboolean JNICALL Java_io_questdb_client_std_Files_truncate
(JNIEnv *e, jclass cl, jint fd, jlong size) {
int res;
Expand Down Expand Up @@ -236,6 +251,18 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_lock
return flock((int) fd, LOCK_EX | LOCK_NB);
}

JNIEXPORT jint JNICALL Java_io_questdb_client_cutlass_qwp_client_sf_cursor_SlotLock_release0
(JNIEnv *e, jclass cl, jint fd) {
if (flock((int) fd, LOCK_UN) != 0) {
return -1;
}
/* Unlock success confirms that the slot is reusable. close() is one-shot:
* POSIX leaves descriptor state unspecified on EINTR, so retrying its
* numeric value could close an unrelated descriptor after reuse. */
(void) close((int) fd);
return 0;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_mkdir0
(JNIEnv *e, jclass cl, jlong lpszPath, jint mode) {
return mkdir((const char *) (uintptr_t) lpszPath, (mode_t) mode);
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/c/share/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_network_Net_send
return com_questdb_network_Net_EOTHERDISCONNECT;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_network_Net_shutdown
(JNIEnv *e, jclass cl, jint fd) {
const int result = shutdown((int) fd, SHUT_RDWR);
return result == -1 && errno == ENOTCONN ? 0 : result;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_network_Net_recv
(JNIEnv *e, jclass cl, jint fd, jlong ptr, jint len) {
ssize_t n;
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/c/share/net.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions core/src/main/c/windows/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,25 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_fsync
return 0;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_fsyncDir0
(JNIEnv *e, jclass cl, jlong lpszName) {
jint fd = open_file((const char *) (uintptr_t) lpszName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS);
if (fd < 0) {
return -1;
}
if (!FlushFileBuffers(FD_TO_HANDLE(fd))) {
SaveLastError();
CloseHandle(FD_TO_HANDLE(fd));
return -1;
}
CloseHandle(FD_TO_HANDLE(fd));
return 0;
}

JNIEXPORT jboolean JNICALL Java_io_questdb_client_std_Files_truncate
(JNIEnv *e, jclass cl, jint fd, jlong size) {
FILE_END_OF_FILE_INFO eof;
Expand Down Expand Up @@ -331,6 +350,20 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_lock
return 0;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_cutlass_qwp_client_sf_cursor_SlotLock_release0
(JNIEnv *e, jclass cl, jint fd) {
OVERLAPPED ov;
memset(&ov, 0, sizeof(ov));
if (!UnlockFileEx(FD_TO_HANDLE(fd), 0, MAXDWORD, MAXDWORD, &ov)) {
SaveLastError();
return -1;
}
/* Unlock success confirms that the slot is reusable. Match POSIX by
* closing once without making handle cleanup part of that signal. */
(void) CloseHandle(FD_TO_HANDLE(fd));
return 0;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_std_Files_mkdir0
(JNIEnv *e, jclass cl, jlong lpszPath, jint mode) {
(void) mode;
Expand Down
14 changes: 14 additions & 0 deletions core/src/main/c/windows/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,20 @@ JNIEXPORT jint JNICALL Java_io_questdb_client_network_Net_configureNonBlocking
return res;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_network_Net_shutdown
(JNIEnv *e, jclass cl, jint fd) {
const int result = shutdown((SOCKET) fd, SD_BOTH);
if (result == SOCKET_ERROR) {
const int error = WSAGetLastError();
if (error == WSAENOTCONN) {
return 0;
}
WSASetLastError(error);
SaveLastError();
}
return result;
}

JNIEXPORT jint JNICALL Java_io_questdb_client_network_Net_recv
(JNIEnv *e, jclass cl, jint fd, jlong addr, jint len) {
const int n = recv((SOCKET) fd, (char *) addr, len, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ public void close() {
}
}

/**
* Shuts down socket traffic without releasing the descriptor or freeing
* buffers that a concurrent I/O worker may still access. The owner must
* call {@link #close()} after joining the worker to complete cleanup.
*/
public void closeTraffic() {
socket.closeTraffic();
}

/**
* Connects to a WebSocket server.
*
Expand Down
Loading
Loading