- debug and release targets now produce both shared and static libs
- obj dirs split into shared/ and static/ to keep fPIC objects isolated
- install no longer depends on release, guards with existence check instead
- build.sh handles privilege escalation for install/uninstall via doas or
sudo, falling back gracefully if already root
- uninstall cleans up static lib alongside shared
- stk_poll: unify load loops to always append on compacted array, removing stale pre-compaction slot indices
- stk_poll: heap-allocate cascade_indices per iteration, removing fixed 256-slot stack bound
- stk_pending_retry: shrink module array to actual count after retry loop completes
- stk_collect_dependents: add capacity parameter and bounds guard before index write
- stk_log_modules: cast module_count to unsigned long for C89 portable %lu on Windows
Replace per-module stk_pending_add() calls in the load holes loop and
append_modules loop with a single shared load_batch[load_count] buffer,
flushed via stk_pending_add_batch() once after both loops complete.
Replace per-module malloc calls in stk_pending_retry and stk_poll
with bulk allocations.
- stk_pending_retry: single realloc to module_count + stk_pending_count
before the retry loop instead of realloc + 1 per module at attempt_load
- stk_poll unload loop: collect cascade deps into a batch array, call
stk_pending_add_batch once after instead of stk_pending_add per module
- stk_poll cascade loop: same pattern, batch collect and add once per
cascade iteration
- Add STK_MOD_DEP_LOG_BUFFER (2048) to stk.h for the dep failure message
buffer size.
- Add stk_log_dependency_failures(index, action) to module.c. Walks all
deps for the given module, skips satisfied ones, and builds a single
log line listing every unmet dep with its reason: "not found" or
"requires <constraint>, have <version>". The action parameter
("Deferring" / "Unloading") lets call sites produce contextually
appropriate messages:
- Deferring 'test_mod_dep': unmet deps: test_mod (not found)
- Unloading 'test_mod_dep': unmet deps: test_mod (not found), renderer (requires ^2.0.0, have 1.3.0)
- Replace the silent defer at init and the vague "unmet dependencies"
cascade log in stk_poll() with calls to stk_log_dependency_failures().
- Refactor the Kahn topological sort into a generic stk_kahn_sort() that
accepts a has_dep callback and an on_cycle callback, eliminating direct
coupling to stk_modules. stk_topo_sort() becomes a thin wrapper using
stk_loaded_has_dep() and stk_log_cycle(). stk_sort_load_order() uses the
same core via stk_batch_has_dep(), which opens tmp files to inspect deps
so simultaneous load events are processed dependency-first without needing
a retry cycle.
- Split stk_module_load() into stk_module_preload(), stk_module_activate(),
stk_module_discard(), and stk_validate_dependencies_single(). preload
handles library loading and metadata only; activate calls init; discard
cleans up without calling shutdown; validate_dependencies_single checks a
single module's deps. stk_module_load() composes these in order and does
not call init if deps are unmet.
- On UNLOAD events in stk_poll(), expand the unload set to include all
transitively dependent loaded modules via stk_collect_dependents(), sort
dependents-first via stk_sort_unload_order(), and unload in that order.
Modules unloaded due to expansion are queued to pending so they reload
automatically when their dependency returns. Remove trim_arrays, now
handled by the compact pass after the unload block.
- On LOAD events with unmet dependencies, add the tmp path to the pending
queue instead of dropping the module. stk_pending_retry() skips already
loaded entries and prunes entries whose file no longer exists. Move the
free_poll label above stk_pending_retry() so retry always runs regardless
of which path exits the event processing block.
- Move stk_dep_t to public header
- Rename stk_set_module_dependencies_fn to stk_set_module_deps_sym
- Change default deps symbol name from stk_mod_dependencies to stk_mod_deps
- Read deps as direct exported stk_dep_t array instead of function call
- Update sentinel check to .id[0] != '\0'
- Default module version to 0.0.0 if not provided or invalid
- Remove deps_func from union in stk_module_load
- Make stk_validate_dependencies and stk_topo_sort non static
- Add extern declarations in stk.c
- Run stk_validate_dependencies after module loads in stk_init
- Validation failure is fatal; unload all modules and return error code
- Run stk_topo_sort after validation, sort failure is logged but not fatal
- Add validate_deps label in stk_poll so all load/unload paths run validation
- Add dep error codes to stk_error_string
- Consolidate handles, function pointers, metadata, and deps into single stk_mod_t
- Remove all separate metadata arrays and index mappings
- Simplify init, free, realloc, load, and unload significantly
- stk.c externs reduced to stk_modules and module_count
- Add tight-packed arrays with index mappings for name, version, and description
- Resolve optional metadata symbols at load time via platform_get_symbol
- Add setter functions for metadata symbol name overrides
- platform_mkdir now checks if directory exists before creating
- Add FILE_ATTRIBUTE_HIDDEN for dot-prefixed directories on Windows
- Create parent mods directory before temp directory
- Move module unload before copy in reload sequence to fix issue on Windows
- Force CMD shell in test makefile on Windows
Test makefile now uses cmd.exe instead of bash on Windows, fixing
syntax errors when running via build.bat.
Reverse enum so lower values = less severe, higher = more severe.
This makes the filter check (level < min_log_level) work correctly.
- DEBUG (0) - least severe, filtered by default
- INFO (1) - default minimum level
- WARN (2) - warnings and above
- ERROR (3) - most severe, always shown
Fixes incorrect filtering where ERROR/WARN were being blocked.
- Update stk_version.h: 0.0.4 → 0.1.0
- Add CHANGELOG entry for 0.1.0 release
- C89 compliance fixes
- Flags bitfield system
- Enhanced logging system
- Update README project status and API reference
- Document new logging functions and configuration
- Replace stk_initialized with stk_flags bitfield
- Add STK_FLAG_INITIALIZED (0x01) and STK_FLAG_LOGGING_ENABLED (0x02)
- Add stk_set_logging_enabled() and stk_is_logging_enabled() API
- Single byte for all boolean state and settings
Logging enabled by default, packs all flags into one byte for efficiency.
BREAKING CHANGE: Public API now uses unsigned char instead of uint8_t
- Remove stdint.h dependency (C99 feature, not C89, I am a fucking idiot)
- Replace uint8_t with unsigned char throughout codebase
- Affects stk_init() return type and internal functions
- Corrects unintended C99 dependency, restoring intended C89 compliance
When spamming file changes rapidly, inotify can report stale UNLOAD/RELOAD
events for modules that were already unloaded by previous events in the same
poll cycle. This caused is_mod_loaded() to return -1, which was then cast to
size_t (18446744073709551615) and used as an array index, causing segfaults.
Additionally, event counts were calculated before validation, causing loops to
run more iterations than valid indices were populated, reading garbage values.
Changes:
- stk.c: Check if is_mod_loaded() returns valid index (>= 0) before adding
to unload/reload lists
- stk.c: Reset and recalculate counts after populating arrays with only valid
indices to prevent loop overrun
- Skip processing events for modules that are no longer loaded
This completes the Linux stability fixes started in v0.0.2.