RFR: 8320655: awt screencast robot spin and sync issues with native libpipewire api
Alexander Zvegintsev
azvegint at openjdk.org
Fri Dec 1 15:03:07 UTC 2023
On Fri, 1 Dec 2023 14:26:39 GMT, Anton Bobrov <duke at openjdk.org> wrote:
>> Sorry for not being clear, I meant by retry to start everything with a new session.
>> And of course, changing the internal API is not a problem as it is quite small and only used in one place.
>>
>> Separate patch is fine, I submitted [JDK-8321176](https://bugs.openjdk.org/browse/JDK-8321176) for this, I can do it, but later.
>
> @azvegint do you think it would make sense to do it in the native code or in the upper level Java code ? AND also how many times do you think it would make sense to retry provided this could be a permanent pipewire error and so it wont be sitting there re-trying with the same error forever ? (EDIT): i see you have mentioned in the bug just 1 retry. i think it would still make sense to do something about the case where even the 2nd attempt does not succeed ie notify the caller somehow (retval/exception) that it has failed.
I think it's better to do it in the native, to avoid extra native-java hops.
As for the number of extra attempts, I think one-two is enough.
Something like this (I haven't tested it thoroughly yet):
diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c
index 6a7c4124935..a7c5aadb1ae 100644
--- a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c
@@ -855,6 +855,32 @@ static void arrayToRectangles(JNIEnv *env,
(*env)->ReleaseIntArrayElements(env, boundsArray, body, 0);
}
+static int makeAnAttempt(
+ const gchar *token,
+ GdkRectangle *requestedArea,
+ GdkRectangle *affectedScreenBounds,
+ gint affectedBoundsLength) {
+ if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) {
+ return pw.pwFd;
+ }
+
+ if (!doLoop(*requestedArea)) {
+ return RESULT_ERROR;
+ }
+
+ while (!isAllDataReady()) {
+ fp_pw_thread_loop_lock(pw.loop);
+ fp_pw_thread_loop_wait(pw.loop);
+ if (hasPipewireFailed) {
+ fp_pw_thread_loop_unlock(pw.loop);
+ doCleanup();
+ return RESULT_ERROR;
+ }
+ fp_pw_thread_loop_unlock(pw.loop);
+ }
+ return RESULT_OK;
+}
+
/*
* Class: sun_awt_screencast_ScreencastHelper
* Method: closeSession
@@ -911,25 +937,17 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl
jx, jy, jwidth, jheight, token
);
- if (!initScreencast(token, affectedScreenBounds, affectedBoundsLength)) {
- releaseToken(env, jtoken, token);
- return pw.pwFd;
- }
-
- if (!doLoop(requestedArea)) {
- releaseToken(env, jtoken, token);
- return RESULT_ERROR;
- }
+ int attemptResult = makeAnAttempt(token, &requestedArea,
+ affectedScreenBounds, affectedBoundsLength);
- while (!isAllDataReady()) {
- fp_pw_thread_loop_lock(pw.loop);
- fp_pw_thread_loop_wait(pw.loop);
- if (hasPipewireFailed) {
- fp_pw_thread_loop_unlock(pw.loop);
+ if (attemptResult) {
+ DEBUG_SCREENCAST("First attempt failed with %i, re-trying...\n", attemptResult);
+ attemptResult = makeAnAttempt(token, &requestedArea,
+ affectedScreenBounds, affectedBoundsLength);
+ if (attemptResult) {
releaseToken(env, jtoken, token);
- return RESULT_ERROR;
+ return attemptResult;
}
- fp_pw_thread_loop_unlock(pw.loop);
}
DEBUG_SCREENCAST("\nall data ready\n", NULL);
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/16794#discussion_r1412217992
More information about the client-libs-dev
mailing list