Skip to content

Does a LINKed module survive in the Job Pack Area between requests? #250

Description

@mgrossmann

Found while scoping #198. Four places in the project describe how a MOD= route
reaches its load module, and they do not agree. Two of them contradict the
source outright.

What the source says

httppcgi() calls http_link(httpc, route->pgm) on every dispatch
(src/httppcgi.c:47) — unconditionally, with no cache and no lookup of a
previously loaded copy. http_link() is __linkds(), the LINK SVC
(src/httplink.c), and it passes a plist carrying httpc->httpd and httpc,
so the module is executed, not merely resolved. There is no startup __load()
anywhere in the dispatch path.

The four claims

Where Claim Verdict
docs/configuration.md:451 "load modules that HTTPD loads at startup via __load() and calls directly through the HTTPX function vector" wrong
docs/development.md:223,227 table rows: "Loaded into server address space at startup"; "Direct function call (~10µs)" wrong
docs/refactoring-backlog.md:628 (P7) "Every CGI dispatch is a __linkds LINK SVC (~50 ms)" matches the source
ecosystem CLAUDE.md "a separate load module that httpd re-LINKs per request" matches the source

The two wrong ones are the user-facing documents, and the performance claim in
development.md is off by roughly three orders of magnitude against P7's own
figure in the same repo — ~10µs for a direct call versus ~50ms for the LINK
that actually happens.

The confusion is understandable: the HTTPX vector is how a module calls back
into the server, and that half of the table is correct. What is wrong is the
inbound direction — how the server reaches the module.

The part that still needs measuring

Settling the wording above needs no MVS time; it is a source read. One adjacent
question does need the machine, and #198 waits on it:

Does the copy LINK brings in survive to the next request? MVS LINK searches
the Job Pack Area first and decrements the responsibility count on return, so
the module may persist in JPA for the address space's life — or be re-fetched
from disk every dispatch. The two readings are both plausible and the sources
disagree here too:

P7 estimating ~50 ms per dispatch leans toward a real fetch each time, but that
is an estimate, not a measurement.

Check: call /.dm twice against a running server and compare free storage
between the two; a second fetch should move it, a JPA hit should not. Read-only,
no code change, a few minutes. (On a current httpd — before 6448dd0 the
display modules cost 262328 bytes of subpool 0 per call and the reading would be
dominated by that.)

Done when

  1. docs/configuration.md and docs/development.md describe the inbound path as
    it is: a LINK SVC per dispatch, not a startup __load() and not a direct
    call. The HTTPX half of both stays as it is — it is correct.
  2. The JPA question is measured and the answer written down once, in whichever
    of these is the right home, with the other places pointing at it rather than
    restating it.
  3. Pre-allocate lazy first-use storage at startup (worker pool, module loads) #198's step 2 is re-scoped on that answer: placement hygiene if the copy
    persists, a per-request disk fetch worth eliminating if it does not.

Note for whoever picks this up

#198's step 2 as written — "touch every Parmlib-registered MOD= once during
initialization" — cannot use the existing path: __linkds() would run the
module with no request, no socket and no HTTPC. __load(NULL, module, &size, &ac)
(libc370 clibos.h:202) is the primitive that loads without executing, with
__delete() as its counterpart. Worth knowing before that step gets estimated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions