3 ms·
Doesn't almost every C library function potentially call getenv()? printf()ing a number requires checking the locale which can be configured via the environment
by kentonv 3y ago
Doesn't almost every C library function potentially call getenv()? printf()ing a number requires checking the locale which can be configured via the environment, after all.
I'd say you shouldn't be calling setenv() at all once you've spawned threads.
- bb88 3y agoBut the question is: Who knows what and what not to do with libc? "But Go compiled it just fine..."
- rollcat 3y agoI build most of my Go binaries with cgo disabled for this, and many other reasons. In case you don't know, cross-building with GOOS/GOARCH will imply CGO_ENABLED=0 unless you also specify CC_FOR_${GOOS}_${GOARCH}; I cross-build most of my code for (and test it on) amd64, arm64, linux, openbsd, and darwin. Go will sometimes link to the local libc for network-related functionality if you don't disable cgo.
- thewakalix 3y agoThat's the entire point of the post and the earlier posts it links to.
- kentonv 3y agoThe post is about getaddrinfo() specifically. It just struck me as odd to call that one out when there are far more common C library calls that use getenv().
- j16sdiz 3y agoThey did a post on mktime() But, yes, in general for libc, if the manpage didn't say it's thread-safe, it is unsafe.
- defrost 3y agoThere's a strong tendency to think of network calls as entirely universal and not tied in any way to to locale settings in the environment. Time, date, physical spellings, ... many things are locale dependant, but socket stuff?. It comes as a Surprise!!, and not the good kind, to many a network programmer with just a few years under their belt to discover threaded networking can segfault because of this. Once you know, you know and don't forget (until next time), but I suspect this was the motivation behind the blog posting, the principal of potentially most surprise.
- raggi 3y agoCorrect. libc is largely thread unsafe.
- masklinn 3y agoThread unsafe is too kind a qualifier, libc is largely thread-broken.
- cryptonector 3y agoDoesn't have to be. Even `strtok()`, `getpwnam()`, etc. can be thread-safe (just not reentrant).
- somat 3y agoI have to admit the conclusion I have reached is that threads are the problem not libc. We really should have embraced a better primitive than "shared memory execution environment"
- panzi 3y agoI think a lot could be fixed with functions that don't access global state, but get that state as an additional parameter. E.g. I would really like `snprintf_l()`/`fprintf_l()` to be supported by glibc. It is supported by FreeBSD, macOS (Darwin), and even Windows (with a `_` prefix for some reason)! Not by GNU libc.
- senkora 3y agoI think that it is generally not reasonable to convert existing large projects to be multithreaded, in the same way that it is generally not reasonable to fully rewrite existing large projects from scratch. The alternative that I have seen be successful, is to achieve parallelism by forking separate processes wherever you would have spawned threads, and then communicate through shared memory regions. It's a lot like having Rust-style unsafe blocks, in that you know that if you are having a thread-safety issue it will definitely be in one of the code sections where you are touching the shared memory region, and not anywhere else. Obviously there's a higher startup cost for forking, but this makes it possible to gain parallelism without breaking all the thread-unsafe code that is certainly in an existing large project.
- j16sdiz 3y ago> I'd say you shouldn't be calling setenv() at all once you've spawned threads. That's why I hate ZeroMQ. They spawn threads and do magics behind your back.
- another2another 3y agoZeroMQ is a big abstraction over sockets. The higher the level of abstractions, the more these things are usually necessary. If you're using a library like that it comes with the territory, and you have to decide for yourself the cost-benefit of using non blocking sockets and async io yourself, or trust a library. Much more fun to write these things yourself sometimes, but I find e.g. libevent a nice somewhere-in-between abstraction level I can be happy with.
- gpderetta 3y agoSure, but library that spawn threads are a pain. It is convenient for the library writer but it always end up being a significant inconvenience for the user.
- cryptonector 3y ago> I'd say you shouldn't be calling setenv() at all once you've spawned threads. Or, you know, get a better C library. https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/getenv.c?r=60b81b86#48 https://src.illumos.org/source/xref/illumos-gate/usr/src/lib...
- chollida1 3y agoCan you explain what point you are trying to get across? I just see a page of code.
- _justinfunk 3y agoJust read the code! /s
- sltkr 3y agoGrandparent didn't just link to "code"; they linked to a five-paragraph comment explaining what is going on. Did you read those comments before you posted your snarky reply? I think the gist of it is that unlike the glibc implementation, the Illumos implementation of getenv() is lock-free and thread-safe.
- _justinfunk 3y agoyou are a joy
- chasil 3y agoThat appears to be the OpenSolaris C library. I imagine that it is meant to convey that the quality is higher in this library than in GNU libc.
- wruza 3y agoAs the link contains a specific line number, I believe gp suggests to read comment blocks. I’m not very interested to dive into details atm, but at least the explanations seem to be on point.
- jwilk 3y agoThe environment variables don't affect locale immediately; only when you call setlocale().