• SyncRetro lobby re-parses its ini files 10 times per lobby entry

    From Rob Swindell@1:103/705 to GitLab issue in main/sbbs on Sun Aug 2 18:40:24 2026
    open https://gitlab.synchro.net/main/sbbs/-/issues/1211

    `exec/load/syncretro_lobby.js`'s `syncretro_lobby_ini()` builds five sections (`[console]`, `[roms]`, `[lobby]`, `[text]`, `[idle]`) by calling `File.iniGetObject()` once per section, on each of two files (the shipped `syncretro.ini` and the sysop's `syncretro.local.ini`). That is **10 calls per lobby entry**.

    Each of those calls re-reads the whole file. `js_iniGetObject()` (`src/sbbs3/js_file.cpp`) calls `iniReadFiles()`, and `iniReadFiles()` (`src/xpdev/ini_file.c`) opens with:

    ```c
    if (fp != NULL)
    rewind(fp);
    list = strListReadFile(fp, NULL, INI_MAX_LINE_LEN);
    ```

    so every call rewinds the descriptor and reads the file from the top.

    ### Scale

    The shipped `syncretro.ini` files are heavily commented, because they are the documentation as well as the defaults:

    | package | bytes |
    |---|---|
    | `xtrn/syncivision/syncretro.ini` | 16327 |
    | `xtrn/syncnes/syncretro.ini` | 17208 |
    | `xtrn/syncarcade/syncretro.ini` | 19819 |

    So one lobby entry reads on the order of 160-200 KB to extract a few KB of distinct settings.

    ### Why it is worth fixing

    A Synchronet install is commonly a network mount, where the round trips rather than the parsing are the cost. This door already has the precedent: ROM discovery used to open and hash every cartridge on every lobby entry, and caching it cut 212 opens to 0 and 62 ms to 13 ms even on a local filesystem (`src/doors/syncretro/LAUNCHER.md`, section 6). This is the same shape of problem in the same code path.

    ### Suggested fix

    Read each file once and slice all five sections out of the single parsed list, instead of one `iniGetObject()` per section.

    The general observation behind it: `File.iniGetObject()` is O(file) per call, so any JS caller pulling several sections out of one file pays that multiple. Caching inside `js_file.cpp` would be the wrong fix, since it would change semantics for a caller that expects to see a file edited between calls; the caller-side fix is the right one here.

    ### Provenance

    Found by a code review of the SyncRetro configuration consolidation (one shipped `syncretro.ini` plus a `syncretro.local.ini` overlay, replacing the former `console.ini` + copied `syncretro.example.ini` scheme). At the time of filing that work is committed locally but not yet pushed, so the code described above is not on master yet. Filed now so the finding is not lost.

    -- *Authored by Claude (Claude Code), on behalf of @rswindell*
    --- SBBSecho 3.37-Linux
    * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)