src/README.md: map the source folder, its threads and its locks - #3875
src/README.md: map the source folder, its threads and its locks#3875mcfnord wants to merge 10 commits into
Conversation
ann0see
left a comment
There was a problem hiding this comment.
I'd aim this at human contributors for now.
AGPL. But I think it's weird as is. I'd think that a HTML comment for the full license would be enough and a visible short link to the license file. But @pljones should judge. I really dislike a wall of text first just stating the license. Nobody reads it. |
I believe if we write for a human audience, we will dramatically improve LLM outcomes "for free". |
Applies @ann0see's review on jamulussoftware#3875: - Intro cut to two sentences; the paragraph about what the file does and does not assert is gone. - File list back to one line each: the SendMessQueue detail, the SockBuf and CProtocol members and the vecChannels name are all readable in the file itself. Kept "the client has one; the server an array of MAX_NUM_CHANNELS", which is in server.h, not channel.cpp. - The three-bullet block after the thread table is one paragraph. The CSoundBase QThread note moves to src/sound/README.md (jamulussoftware#3873), where a reader meets the class; the send/receive clocking bullet is dropped, as the table above already carries it. The parenthetical about how the thread identities were checked is dropped too: it describes the method, not the code, and the util.cpp TODO makes the point on its own. 122 lines to 105. No claim changed.
CSoundBase derives from QThread, so a reader can reasonably expect a sound thread. There is none: no override of run() and no call to start() exists in the sound layer -- the only two run() overrides in src/ are CHighPrecisionTimer (util.h) and CSocketThread (socket.h). Audio callbacks always arrive on driver-owned threads. Moved here from the src/README.md draft (jamulussoftware#3875), where it sat under the thread table; this is the file that introduces CSoundBase.
There was a problem hiding this comment.
Maybe a separate Channel.md as it's pretty much "here's what Jamulus really is".
There was a problem hiding this comment.
No. I think we should have specifics in the code directly.
There was a problem hiding this comment.
I think we should have specifics in the code directly.
You said this somewhere else... these are Markdown files in the repo, which means "in the code" to me, but are you saying you'd prefer detailed comments inline within C++ source code files?
There was a problem hiding this comment.
Have a somewhat larger comment in the cpp or h file describing roughly what this file does/fits into the architecture. The markdown files have a very high level description or none at all.
E.g. the protocol has in source file docs:
Lines 47 to 72 in 4a43f6f
… condition Two rows of the Threads table were wrong, both found by binding each quantified sentence to a command that would make it false. The CSocketThread row said "Protocol frames are not parsed here". CProtocol::ParseMessageFrame is called on exactly that thread (socket.cpp:643, its only call site) and does the tag, length and CRC validation plus extraction of the body, ID and counter. What crosses to the main thread is the message body, via the queued ProtocolMessageReceived signal, where ParseMessageBody runs it. The protocol API splits frame from body by name and the row asserted the inverse; the Qt main thread row inherited the same error and now says "message body". The CThreadPool row said "server with --multithreading". CServer's constructor also requires more than one core: on idealThreadCount() == 1 it logs "found only one core, disabling multithreading", clears the flag and creates no pool. A single-core server is a normal deployment, so the row described threads that do not exist there. Added to the frame-cycle paragraph as well. Also collapses the blank lines left in the licence block by an earlier suggestion apply. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
pljones on jamulussoftware#3875: "Doesn't need these lines. This only applied to existing files. New files should only have the AGPL header." -- the "As of Jamulus 3.12.1dev" transition note is dropped. A file created after 3.12.1dev has no pre-3.12.1dev history for it to describe. tools/update-copyright-notices.sh carries that sentence only in its own header comment and does not scan .md files for it, so nothing depends on it being here. "Section, laid out as bullets like the shared code. Same for the following ones." -- Client only and Server only are bulleted like the shared list, one line per file with what it holds. "Does this mean it's unused?" on CServer::MutexWelcomeMessage -- no, it is taken in OnNewConnection and SetWelcomeMessage. But it is not taken by the other three readers of strWelcomeMessage (OnCLReqServerFeatures, OnCLReqWelcomeMessage, GetWelcomeMessage), and all five accessors are reached on the main thread: the two CL slots hang off ConnLessProtocol, whose signals are emitted on the main thread behind the queued OnProtocolCLMessageReceived, and GetWelcomeMessage is called from serverdlg, serverrpc and settings. The bullet now says so rather than standing bare. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
🤖 AI: Pushed. Two of these are corrections to the Threads table, found by binding each quantified sentence to a command that would make it false rather than one that confirms it. The The The rest is review follow-up: the licence transition note is dropped from this new file, Client only and Server only are bulleted like the shared list, and the blank lines an earlier suggestion-apply left in the header block are collapsed. |
…o, headings ann0see on jamulussoftware#3875, 2026-08-31: "I still don't like the license disclaimer here. I think this confuses people and agents. There must be a short way to state that it's AGPL licensed (more details in the COPYING file)" -- and, on the same point in the conversation, "a HTML comment for the full license would be enough and a visible short link to the license file". The notice moves into an HTML comment and the visible form is one line linking ../COPYING. pljones had already settled the content: AGPL only, no historical GPL paragraph. "# Main Jamulus codebase" and "This directory contains the main code of Jamulus." -- both suggestions applied verbatim. "## Jamulus Architecture / ### Threading", plus "1-2 sentences about the very general architecture ... especially the datapath from input device, client, encoding/decoding, server, mixin, client. But very brief" -- four lines. Every clause is from the code: the client encodes in ProcessAudioDataIntern and hands the packet to Channel.PrepAndSendPacket; CSocket is SOCK_DGRAM (socket.cpp:192, 252); CServer::OnTimer decodes each channel (server.cpp:986); MixEncodeTransmitData sums every client j into the target channel's buffer with vecvecfGains[iChanCnt][j], which is filled from vecChannels[iCurChanID].GetGain(...) -- the listening channel's own gain table, so the mix is per-client; the result is re-encoded (server.cpp:1282) and sent. The client's own callback then does Channel.GetData followed by opus_custom_decode into the sound card buffer. Locks becomes a subheading so the hierarchy holds. "I guess we could drop this section." / "Yes. Please drop it." -- the "Not yet documented" section is gone. pljones asked whether the connection lifecycle belonged in a separate Channel.md; ann0see answered "No. I think we should have specifics in the code directly", so no such file is added. Also fixed: the CHighPrecisionTimer row of the thread table carried a truncated class name, "CHighPrecisionT" followed by a U+2026 ellipsis, so a grep for the class did not find the row that describes it. Earlier, still-open note from ann0see -- "you should probably not describe too much of the file content ... So here: Implements the channel + jitter buffer used for Server and Client." -- the channel.cpp bullet loses its second sentence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as outdated.
This comment was marked as outdated.
|
|
||
| # Main Jamulus codebase | ||
|
|
||
| Licensed under the AGPL 3.0 or any later version; full text in [../COPYING](../COPYING). |
There was a problem hiding this comment.
@pljones do we really need to put the full license text - even as comment - into the file? It's better now though (since we have this short disclaimer). For code the header is fine, but for markdown files it just seems odd.
ann0see
left a comment
There was a problem hiding this comment.
I'll need to verify the accuracy, but from the philosophy and style, I think it's good now. Basically serves as index which is good.
MY LLM WROTE:
Short description of changes
src/has no README. This adds one: a map for a reader new to the code — which class lives where, which threads exist at runtime, and which lock protects what. Same shape as the section recently proposed forsrc/sound/README.mdin #3873: it describes how the code behaves today, asserts no intent, and ends with an explicit list of what is still missing.What it covers:
CSocketThread, the audio driver threads,CHighPrecisionTimer's thread, theCThreadPoolworkers, the recorder thread, and the connect dialog's use of the global pool. Followed by the three facts easiest to miss: the server's complete frame cycle (CServer::OnTimer) executes on the main thread — theTimeCriticalPrioritytimer thread only paces a queuedemit timeout()(confirmed with a debugger on Linux, and the TODO inutil.cppsays the same);CSoundBaseinheritsQThreadbut that thread is never started; the client sends audio from inside the driver callback while receiving onCSocketThread.MutexSocketBuf,CSocket::Mutex,CServer::Mutexincluding exactly which part ofOnTimerholds it,CChannel::Mutex,MutexConvBuf), each with what it protects and the threads that take it, plus one line each for the smaller ones.The thread table is measured, not read: each identity was confirmed by breaking on the function in a release build under gdb on Linux and recording which thread hit (
CServer::OnTimerandCProtocol::ParseMessageBodyon the main thread,CServer::PutAudioDataandCChannel::PutAudioDataonCSocketThread,CClient::ProcessAudioDataInternon the JACK callback thread,CHighPrecisionTimer::runon its own thread).Two design choices, offered for discussion since later doc files could follow the pattern:
[channel.cpp](channel.cpp),[../docs/JAMULUS_PROTOCOL.md](../docs/JAMULUS_PROTOCOL.md). Rendered on GitHub, the map becomes browseable: every named file is one click away. Read raw in a terminal or an editor, each link degrades to the path plus punctuation, so the text still works for a reader without a browser.grepfinds them from either the rendered or the raw form.CHANGELOG: SKIP
Context: Fixes an issue?
No issue. Follows #3873, which starts the sound-layer half of the same documentation; this file links to it rather than repeating it.
Does this change need documentation? What needs to be documented and how?
This is the documentation. Developer-facing, so it belongs next to the code rather than on the website.
Status of this Pull Request
Working implementation. Every statement is checkable against the tree at the commit it was written on, and the thread identities were verified at runtime rather than inferred from the source.
What is missing until this pull request can be merged?
Review. One open question for reviewers: whether the license header on a brand-new documentation file should carry the full historical GPL paragraph or only the AGPL block used here.
Checklist
No checks run on this one:
autobuild.ymlcarriespaths-ignore: '**README.md'andcoding-style-check.ymlonly triggers on**.cpp/**.h, so the fourth box stays unticked rather than claiming a green run that never happened.