# Extended 5.26 — FFI executeWorkerTask leaks WorkerTask

Bug ref      : pharo.md §5.26
Severity     : LOW (memory leak; per-task)
File         : ffi/src/worker/worker.c
Lines (HEAD) : 210-219

## Problem

```c
void executeWorkerTask(Worker *worker, WorkerTask *task) {
    ffi_call(
             task->cif,
             task->anExternalFunction,
             task->returnHolderAddress,
             task->parametersAddress);
    
    signalSemaphoreWithIndex(task->semaphoreIndex);
}
```

`task` is heap-allocated by `worker_task_new_callout` (or similar)
in the task queue. After execution and semaphore signal, the
`WorkerTask` is never freed. One leak per FFI worker call.

## Fix

```diff
diff --git a/src/ffi/worker/worker.c b/src/ffi/worker/worker.c
index f3a53d4d1..627289534 100644
--- a/src/ffi/worker/worker.c
+++ b/src/ffi/worker/worker.c
@@ -208,12 +208,16 @@ void *worker_run(void *aWorker) {
 }
 
 void executeWorkerTask(Worker *worker, WorkerTask *task) {
-    
+
     ffi_call(
              task->cif,
              task->anExternalFunction,
              task->returnHolderAddress,
              task->parametersAddress);
-    
+
     signalSemaphoreWithIndex(task->semaphoreIndex);
+
+    /* Task was allocated by worker_task_new_callout; free it now that
+     * the caller has been signalled. Previously leaked per call. */
+    free(task);
 }

```

## Test plan

- Run a load of 10⁶ FFI worker callouts; verify steady-state RSS
  is flat (before: grows by sizeof(WorkerTask) per call).
- Verify no double-free if the caller path also frees the task
  (audit caller; current code does not).

## Risk notes

- If any caller already frees the task on the worker side, this
  patch double-frees. Audit `worker_add_call` → `worker_next_call`
  → `executeWorkerTask` chain before merging.
