* simplify c api by merging redudant functions; deprecate more functions no longer in use
simplify c api by merging redudant functions; deprecate more functions no longer in use
update docs
* remove deprecated methods
* fix: ensure consistent token socket path on the sender and receiver end
* address PR #129 review comments
- unix_socket_path.h: replace fixed-size PATH_MAX buffer with a
two-step confstr probe (nullptr/0 to learn the size, then a
std::vector<char>). Apple's per-user temp dir can exceed PATH_MAX
on some configurations; the truncated fallback to /tmp would
reintroduce the exact parent/child path mismatch this helper is
meant to prevent.
- token_receiver.cpp: stack-allocate QLocalServer instead of new +
deleteLater. The Qt event loop is not guaranteed to be running on
the receiver thread, so deleteLater would leak; RAII makes every
exit path (including listen() failure) clean up.
- tests/test_token_exchange.cpp: add a regression test that pins the
TMPDIR-unset behaviour. The new test
RoundTrip_SucceedsWithTmpdirUnset unsets TMPDIR (and
LOGOS_INSTANCE_ID, which earlier tests may have left set via
LogosInstance::id) and asserts both sender and receiver agree on
the helper-resolved socket path. Also re-route the existing
tmpDir() helper through ::logos::qtCompatibleTempDir() so the
instance-id tests stay correct under the same conditions.
`s_processes` is a namespace-scope static (constructed before main),
while `IoRuntime` is a function-local static (constructed lazily on
first use, from main). C++ destroys statics in reverse construction
order, so at exit `~IoRuntime` fires first — tearing down the
asio::io_context and its epoll_reactor — and then `~s_processes`
runs, dropping `shared_ptr<ProcessEntry>`s whose dtors close asio
handles tied to the already-freed reactor. The resulting
use-after-free corrupts the heap and aborts logoscore on shutdown
(SIGABRT 134 / sometimes SIGSEGV 139, glibc reports
"corrupted size vs. prev_size"). Caught by valgrind:
Invalid read of size 1
at boost::asio::detail::epoll_reactor::deregister_descriptor
by io_object_impl::~io_object_impl
by std::_Hashtable<..., shared_ptr<ProcessEntry>, ...>::~_Hashtable
by __cxa_finalize
Address ... free'd
by boost::asio::detail::epoll_reactor::~epoll_reactor
by IoRuntime::~IoRuntime
Move ~IoRuntime out-of-line so it can reach s_processes, and have it
clear the map after stopping the worker thread but before ctx itself
is torn down by the field destructors. Each ProcessEntry's asio
handles are now released against a live reactor; the later
~s_processes then runs against an empty map.
Surfaced by logos-test-modules: 149/158 tests failed in CI
(intermittently 9–149 across machines, depending on malloc layout).
With this fix: 158 passed, 0 failed.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two related fixes to the parent-side token handoff to a child module
process, both motivated by races / silent failures observed in the
docker smoke matrix.
1. Replace the hard-coded 10×100ms retry loop with a deadline-driven
loop, default budget 5000ms (configurable via a new max_wait_ms
parameter). The previous 900ms cap was tight enough that on a cold
child — dynamic loader + Qt platform bring-up + CLI11 parse +
plugin loadFromPath — the parent would give up before the child
bound its QtTokenReceiver socket, leaving a half-loaded module
with a misleading "Failed to connect to token socket" error. New
tests pin both ends of the contract:
SendToken_FailsFast_WhenSocketNeverAppears — bails within budget
SendToken_SucceedsAfterDelay — accepts late binders
test_token_exchange's WrongName_FailsCleanlyWithinTimeout bound
loosened from <5000ms to <5500ms because the deadline check can
overshoot by ~one poll interval (50ms) plus syscall slack.
2. Validate the computed Unix socket path against
sockaddr_un::sun_path (~104 bytes on macOS, ~108 on Linux) before
strncpy. Long TMPDIR + module name + LOGOS_INSTANCE_ID combos
would otherwise silently truncate, leaving the parent connecting
to the wrong socket while the child binds the full path. Fail
loudly instead.
* refactor: move logost_host to become one of the possible runtimes
refactor: move logost_host to become one of the possible runtimes
remove shim
revert some unnecessary changes
update docs
update docs
revert unnecessary changes
simplify
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix stdout and stderr redirection
* address PR review: strip trailing CR on pipe flush + add split-stream test
- handleRead: when flushing a partial line on pipe close, apply the same
trailing-CR trim that the newline loop does.
- tests: add StartProcess_OnOutput_SplitsStdoutAndStderr to assert that
both pipes drain and onOutput fires with the correct isStderr flag.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* add unload with dependents method
* address second-round PR review comments
- plugin_registry.cpp: registerPlugin always writes dependencies and
recomputes reverse edges (previously gated on !empty, which kept
dependents stale when a plugin was registered with {} after another
had already declared a dep on it, and also left callers with no way
to clear forward edges).
- plugin_manager.cpp: getDependencies filters to known modules so the
output matches the "among known modules" contract the header
documents. pluginDependencies can return raw manifest names that
aren't installed; filter at this boundary.
- README.md: thread-safety section no longer claims logos_core_refresh_plugins
is serialised by the load/unload mutex — it isn't; it goes through the
registry's reader-writer lock.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update src/logos_core/plugin_registry.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* remove excessive logs
* use a PluginInfo registry instead of various variables
* simplify: plugin_loader is no longer needed
* move plugin launcher as a separate concern
* abstract/move some of proxy api logic to cpp-sdk
* use qFatal
* remove jsonParamToQVariant
* simplify using qFatal
* remove old interface.h use logos-module
* remove local code for now (will be re-added later)
* remove unnecessary methods and qDebugs
* update flake
---------
Co-authored-by: Logos Workspace <logos@workspace.local>