Skip to content

Commit f481231

Browse files
committed
Honour --vm.XstartOnFirstThread on macos language launchers.
1 parent 3b24427 commit f481231

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

sdk/src/org.graalvm.launcher.native/src/launcher.cc

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
#define IS_VM_LIBRARY_PATH_ARG(ARG) STARTS_WITH(ARG, VM_LIBRARY_PATH_ARG_PREFIX)
119119
#define IS_VM_STACK_SIZE_ARG(ARG) STARTS_WITH(ARG, VM_STACK_SIZE_ARG_PREFIX)
120120
#define IS_VM_ARG_FILE_ARG(ARG) STARTS_WITH(ARG, VM_ARG_FILE_ARG_PREFIX)
121+
#define IS_VM_START_ON_FIRST_THREAD(ARG) (ARG == "--vm.XstartOnFirstThread")
121122

122123
#define NMT_ARG_NAME "XX:NativeMemoryTracking"
123124
#define NMT_ENV_NAME "NMT_LEVEL_"
@@ -364,7 +365,8 @@ static void parse_vm_option(
364365
std::ostringstream *cp,
365366
std::ostringstream *modulePath,
366367
std::ostringstream *libraryPath,
367-
size_t* stack_size,
368+
size_t *stack_size,
369+
bool *startOnFirstThread,
368370
std::string_view option) {
369371
if (IS_VM_CP_ARG(option)) {
370372
*cp << CP_SEP_STR << option.substr(VM_CP_ARG_OFFSET);
@@ -379,6 +381,10 @@ static void parse_vm_option(
379381
} else if (IS_VM_ARG_FILE_ARG(option)) {
380382
std::string arg_file(option.substr(VM_ARG_FILE_ARG_OFFSET));
381383
expand_vm_arg_file(arg_file.c_str(), vmArgs, cp, modulePath, libraryPath, stack_size);
384+
#if defined (__APPLE__)
385+
} else if (IS_VM_START_ON_FIRST_THREAD(option)) {
386+
*startOnFirstThread = true;
387+
#endif
382388
} else if (IS_VM_ARG(option)) {
383389
if (IS_VM_STACK_SIZE_ARG(option)) {
384390
*stack_size = parse_size(option.substr(VM_STACK_SIZE_ARG_OFFSET));
@@ -555,13 +561,14 @@ struct MainThreadArgs {
555561
bool jvmMode;
556562
std::string libPath;
557563
size_t stack_size{};
564+
bool startOnFirstThread;
558565
std::vector<std::string> vmArgs;
559566
std::vector<std::string> optionVarsArgs;
560567
};
561568

562569
/* parse the VM arguments that should be passed to JNI_CreateJavaVM */
563570
static void parse_vm_options(struct MainThreadArgs& parsedArgs) {
564-
auto& [argc, argv, exeDir, jvmMode, _, stack_size, vmArgs, optionVarsArgs] = parsedArgs;
571+
auto& [argc, argv, exeDir, jvmMode, _, stack_size, startOnFirstThread, vmArgs, optionVarsArgs] = parsedArgs;
565572

566573
/* check if vm args have been set on relaunch already */
567574
int vmArgCount = 0;
@@ -715,7 +722,7 @@ static void parse_vm_options(struct MainThreadArgs& parsedArgs) {
715722
const char *launcherDefaultVmArgs[] = LAUNCHER_DEFAULT_VM_ARGS;
716723
for (int i = 0; i < sizeof(launcherDefaultVmArgs)/sizeof(char*); i++) {
717724
if (IS_VM_ARG(std::string(launcherDefaultVmArgs[i]))) {
718-
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, launcherDefaultVmArgs[i]);
725+
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, &startOnFirstThread, launcherDefaultVmArgs[i]);
719726
}
720727
}
721728
#endif
@@ -724,7 +731,7 @@ static void parse_vm_options(struct MainThreadArgs& parsedArgs) {
724731
if (!relaunch) {
725732
/* handle CLI arguments */
726733
for (int i = 1; i < argc; i++) {
727-
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, argv[i]);
734+
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, &startOnFirstThread, argv[i]);
728735
}
729736

730737
/* handle optional vm args from LanguageLibraryConfig.option_vars */
@@ -745,12 +752,12 @@ static void parse_vm_options(struct MainThreadArgs& parsedArgs) {
745752
while ((next = optionLine.find(" ", last)) != std::string::npos) {
746753
option = optionLine.substr(last, next-last);
747754
optionVarsArgs.push_back(option);
748-
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, option);
755+
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, &startOnFirstThread, option);
749756
last = next + 1;
750757
};
751758
option = optionLine.substr(last);
752759
optionVarsArgs.push_back(option);
753-
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, option);
760+
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, &startOnFirstThread, option);
754761
}
755762
#endif
756763
} else {
@@ -769,7 +776,7 @@ static void parse_vm_options(struct MainThreadArgs& parsedArgs) {
769776
std::cerr << "VM arguments specified: " << vmArgCount << " but argument " << i << "missing" << std::endl;
770777
break;
771778
}
772-
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, cur);
779+
parse_vm_option(&vmArgs, &cp, &modulePath, &libraryPath, &stack_size, &startOnFirstThread, cur);
773780
/* clean up env variable */
774781
setenv(envKey, "");
775782
}
@@ -865,7 +872,7 @@ int main(int argc, char *argv[]) {
865872

866873

867874
/* parse VM args */
868-
struct MainThreadArgs parsedArgs{argc, argv, exeDir, jvmMode, libPath, 0};
875+
struct MainThreadArgs parsedArgs{argc, argv, exeDir, jvmMode, libPath, 0, false};
869876
parse_vm_options(parsedArgs);
870877
size_t stack_size = parsedArgs.stack_size;
871878

@@ -883,10 +890,12 @@ int main(int argc, char *argv[]) {
883890
size_t main_thread_stack_size = current_thread_stack_size();
884891
bool use_new_thread = stack_size > main_thread_stack_size;
885892
#if defined (__APPLE__)
886-
/* On macOS, always create a dedicated "main" thread for the JVM.
893+
/* On macOS, default to creating a dedicated "main" thread for the JVM.
887894
* The actual main thread must run the UI event loop (needed for AWT).
895+
* It can be overridden with -XstartOnFirstThread, this is needed to
896+
* use other UI frameworks that *do* need to run on the main thread.
888897
*/
889-
use_new_thread = true;
898+
use_new_thread = !parsedArgs.startOnFirstThread;
890899

891900
if (jvmMode) {
892901
if (!load_jli_lib(exeDir)) {
@@ -965,7 +974,7 @@ int main(int argc, char *argv[]) {
965974
}
966975

967976
static int jvm_main_thread(struct MainThreadArgs& parsedArgs) {
968-
auto& [argc, argv, _, jvmMode, libPath, stack_size, vmArgs, optionVarsArgs] = parsedArgs;
977+
auto& [argc, argv, _, jvmMode, libPath, stack_size, startOnFirstThread, vmArgs, optionVarsArgs] = parsedArgs;
969978

970979
/* load VM library - after parsing arguments s.t. NMT
971980
* tracking environment variables are already set */

0 commit comments

Comments
 (0)