Bound in-flight file opens in exec-server (#50162)

## Why

The per-connection limit of 128 file read handles was checked only after opening the file, leaving pending opens outside the limit.

## What changed

Reserve a semaphore permit before polling the file-open future, counting pending opens and registered handles against the same limit. Release capacity when an open fails or is cancelled, or when a handle closes, even if a read still retains the file.

Use synchronous handle-table locks that never cross an await, and recheck duplicate IDs after opening to preserve the winning handle during concurrent opens.

## Testing

Add tests for stalled-open progress, pending-open admission limits, permit cleanup after failure or cancellation, capacity reuse while a file remains in use, and concurrent duplicate IDs.

GitOrigin-RevId: caabf38c74dda5951f2fc75234a7149daaa01263
This commit is contained in:
Adam Perry @ OpenAI
2026-10-02 03:31:52 +00:00
committed by copyberry
parent e7ea5f4a86
commit d25c114d49
5 changed files with 217 additions and 44 deletions
@@ -70,7 +70,7 @@ impl FileSystemHandler {
}
pub(crate) async fn shutdown(&self) {
self.file_handles.close_all().await;
self.file_handles.close_all();
}
pub(crate) async fn discover_capability_roots(
@@ -131,14 +131,13 @@ impl FileSystemHandler {
"exec-server does not support writable file streams".to_string(),
));
}
let file = self
.file_system
.open_file_for_read(&params.path, params.sandbox.as_ref())
.await
.map_err(map_fs_error)?;
let handle_id = self
.file_handles
.open(params.handle_id, file)
.open(
params.handle_id,
self.file_system
.open_file(&params.path, params.sandbox.as_ref()),
)
.await
.map_err(map_fs_error)?;
Ok(FsOpenResponse { handle_id })
@@ -176,7 +175,7 @@ impl FileSystemHandler {
params: FsCloseParams,
) -> Result<FsCloseResponse, JSONRPCErrorError> {
validate_file_handle_id(&params.handle_id)?;
self.file_handles.close(&params.handle_id).await;
self.file_handles.close(&params.handle_id);
Ok(FsCloseResponse {})
}