P2.5 phase 1 of 2: build + validate a config and allocate a
handle EXACTLY like rdb_ocean_create_from_string, but stop
there — does NOT run engine_setup or map the device. Claims the
single-live-handle guard immediately (a second concurrent
create/create_pending is refused from this point on, even though
engine_setup has not yet touched any process-global state — the
invariant is “one handle mid-create at a time”, not merely “one
finished one”).
Between this call and rdb_ocean_create_finalize, the
rdb_ocean_stage_* entry points below inject geometry
(bathymetry, grid metrics, topology) that engine_setup consumes
— exactly the window passive-tracer registration already needed
(registry_locked closes at enter_data, rdb_multilayer_state.F90).
A caller with no geometry to inject has no reason to use this
entry point — rdb_ocean_create_from_string remains the
normal one-call path and is completely unaffected by this phase.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(kind=c_char, len=1), | intent(in) | :: | nml_text(nml_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | nml_len | ||
| type(c_ptr), | intent(out) | :: | handle_out |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(c_ptr), | private | :: | c_handle | ||||
| type(ocean_handle_t), | private, | pointer | :: | h | |||
| character(len=:), | private, | allocatable | :: | text |
function rdb_ocean_create_pending(nml_text, nml_len, handle_out) & result(status) bind(c, name="rdb_ocean_create_pending") !! P2.5 phase 1 of 2: build + validate a config and allocate a !! handle EXACTLY like `rdb_ocean_create_from_string`, but stop !! there — does NOT run `engine_setup` or map the device. Claims the !! single-live-handle guard immediately (a second concurrent !! create/create_pending is refused from this point on, even though !! `engine_setup` has not yet touched any process-global state — the !! invariant is "one handle mid-create at a time", not merely "one !! finished one"). !! !! Between this call and `rdb_ocean_create_finalize`, the !! `rdb_ocean_stage_*` entry points below inject geometry !! (bathymetry, grid metrics, topology) that `engine_setup` consumes !! — exactly the window passive-tracer registration already needed !! (`registry_locked` closes at `enter_data`, `rdb_multilayer_state.F90`). !! A caller with no geometry to inject has no reason to use this !! entry point — `rdb_ocean_create_from_string` remains the !! normal one-call path and is completely unaffected by this phase. integer(c_int), intent(in), value :: nml_len character(kind=c_char), intent(in) :: nml_text(nml_len) type(c_ptr), intent(out) :: handle_out integer(c_int) :: status type(c_ptr) :: c_handle type(ocean_handle_t), pointer :: h character(len=:), allocatable :: text handle_out = c_null_ptr call error_ring_clear() if (g_handle_live) then call error_ring_push("rdb_ocean_create_pending: a live ocean handle "// & "already exists in this process (multi-instance is not "// & "supported) — destroy it before creating another") status = int(OCEAN_STATUS_ERR_ALREADY_EXISTS, c_int) return end if call c_to_f_string(nml_text, nml_len, text) call build_pending_handle(text, c_handle, h, status) if (status /= int(OCEAN_STATUS_OK, c_int)) return ! already destroyed h%is_pending = .true. g_handle_live = .true. handle_out = c_handle end function rdb_ocean_create_pending