@@ -370,7 +370,10 @@ void taskingDestroyProcess(g_process* process)
370370
371371g_task* taskingCreateTask (g_virtual_address eip, g_process* process, g_security_level level)
372372{
373- g_task* task = (g_task*) heapAllocateClear (sizeof (g_task));
373+ auto task = (g_task*) heapAllocateClear (sizeof (g_task));
374+ if (!task)
375+ return nullptr ;
376+
374377 _taskingInitializeTask (task, process, level);
375378 task->type = G_TASK_TYPE_DEFAULT;
376379
@@ -479,13 +482,13 @@ void taskingProcessKillAllTasks(g_pid pid)
479482
480483g_spawn_result taskingSpawn (g_fd fd, g_security_level securityLevel)
481484{
482- g_task* caller = taskingGetCurrentTask ();
485+ g_task* parent = taskingGetCurrentTask ();
483486
484487 // Create target process & task
485- g_spawn_result res;
488+ g_spawn_result res{} ;
486489 res.process = taskingCreateProcess (securityLevel);
487- g_task* newTask = taskingCreateTask (0 , res.process , securityLevel);
488- if (!newTask )
490+ g_task* child = taskingCreateTask (0 , res.process , securityLevel);
491+ if (!child )
489492 {
490493 logInfo (" %! failed to create main thread to spawn binary" , " elf" );
491494 res.status = G_SPAWN_STATUS_TASKING_ERROR;
@@ -494,42 +497,35 @@ g_spawn_result taskingSpawn(g_fd fd, g_security_level securityLevel)
494497
495498 // Clone FD to target process
496499 g_fd targetFd;
497- auto cloneStat = filesystemProcessCloneDescriptor (caller ->process ->id , fd, res.process ->id , G_FD_NONE, &targetFd);
500+ auto cloneStat = filesystemProcessCloneDescriptor (parent ->process ->id , fd, res.process ->id , G_FD_NONE, &targetFd);
498501 if (cloneStat != G_FS_CLONEFD_SUCCESSFUL)
499502 {
500- logInfo (" %! failed to clone executable FD to target process" , " elf" );
503+ logInfo (" %! failed to clone binary FD to target process" , " elf" );
501504 res.status = G_SPAWN_STATUS_IO_ERROR;
502505 return res;
503506 }
504507
505508 // Provide spawn arguments
506509 res.process ->spawnArgs = (g_process_spawn_arguments*) heapAllocateClear (sizeof (g_process_spawn_arguments));
510+ res.process ->spawnArgs ->parent = parent->id ;
507511 res.process ->spawnArgs ->fd = targetFd;
508512 res.process ->spawnArgs ->securityLevel = securityLevel;
509513
510514 // Set kernel-level entry
511- taskingStateReset (newTask , (g_address) &taskingSpawnEntry, G_SECURITY_LEVEL_KERNEL);
515+ taskingStateReset (child , (g_address) &taskingSpawnEntry, G_SECURITY_LEVEL_KERNEL);
512516
513517 // Start thread & wait for spawn to finish
514- newTask->spawnFinished = false ;
518+ INTERRUPTS_PAUSE;
519+ child->spawnFinished = false ;
515520
516- mutexAcquire (&caller->lock );
517- caller->status = G_TASK_STATUS_WAITING;
518- caller->waitsFor = " spawn" ;
519- mutexRelease (&caller->lock );
520- waitQueueAdd (&res.process ->waitersSpawn , caller->id );
521- taskingAssignBalanced (newTask);
521+ mutexAcquire (&parent->lock );
522+ parent->status = G_TASK_STATUS_WAITING;
523+ parent->waitsFor = " spawn" ;
524+ mutexRelease (&parent->lock );
522525
523- while (!newTask->spawnFinished )
524- {
525- INTERRUPTS_PAUSE;
526- mutexAcquire (&caller->lock );
527- caller->status = G_TASK_STATUS_WAITING;
528- caller->waitsFor = " spawn-rep" ;
529- mutexRelease (&caller->lock );
530- taskingYield ();
531- INTERRUPTS_RESUME;
532- }
526+ taskingAssignBalanced (child);
527+ taskingYield ();
528+ INTERRUPTS_RESUME;
533529
534530 // Take result
535531 res.status = res.process ->spawnArgs ->status ;
@@ -556,7 +552,8 @@ void taskingSpawnEntry()
556552 if (loadRes.status != G_SPAWN_STATUS_SUCCESSFUL)
557553 {
558554 logInfo (" %! failed to load binary to current address space" , " elf" );
559- waitQueueWake (&process->waitersSpawn );
555+ auto parent = taskingGetById (process->spawnArgs ->parent );
556+ taskingWake (parent);
560557 taskingExit ();
561558 }
562559
@@ -569,16 +566,18 @@ void taskingSpawnEntry()
569566
570567void taskingFinalizeSpawn (g_task* task)
571568{
569+ INTERRUPTS_PAUSE;
572570 auto process = task->process ;
573571 task->securityLevel = process->spawnArgs ->securityLevel ;
574572 taskingStateReset (task, process->spawnArgs ->entry , task->securityLevel );
575- waitQueueWake (&process->waitersSpawn );
576573
577- INTERRUPTS_PAUSE;
574+ task->spawnFinished = true ;
575+ auto parent = taskingGetById (process->spawnArgs ->parent );
576+ taskingWake (parent);
577+
578578 mutexAcquire (&task->lock );
579579 task->status = G_TASK_STATUS_WAITING;
580580 task->waitsFor = " wake-after-spawn" ;
581- task->spawnFinished = true ;
582581 mutexRelease (&task->lock );
583582 taskingYield ();
584583 INTERRUPTS_RESUME;
@@ -594,3 +593,14 @@ void taskingWaitForExit(g_tid joinedTid, g_tid waiter)
594593 waitQueueAdd (&task->waitersJoin , waiter);
595594 mutexRelease (&task->process ->lock );
596595}
596+
597+ void taskingWake (g_task* task)
598+ {
599+ if (task)
600+ {
601+ mutexAcquire (&task->lock );
602+ if (task->status == G_TASK_STATUS_WAITING)
603+ task->status = G_TASK_STATUS_RUNNING;
604+ mutexRelease (&task->lock );
605+ }
606+ }
0 commit comments