On Friday, May 31, 2024 10:07:23 AM MDT Andy Valencia via Digitalmars-d-learn wrote: > I'm coding a server which takes TCP connections. I end up in the > main thread with .accept() which hands me a Socket. I'd like to > hand this off to a spawn()'ed thread to do the actual work. > > Aliases to mutable thread-local data not allowed. > > Is there some standard way to get something which _isn't_ in TLS? > Or do I have to drop back to file descriptors and do my own > socket handling? > > TIA, > Andy
Strictly speaking, unless you're dealing with a module or static-level variable, the object is not in TLS. It's treated as thread-local by the type system, and the type system will assume that no other thread has access to it, but you can freely cast it to shared or immutable and pass it across threads. It's just that it's up to you to make sure that you don't have a thread-local reference to shared data that isn't protected in a fashion that accessing the thread-local references is guarantee to be thread-safe (e.g. the appropriate mutex has been locked). So, if you're just passing it to another thread, and that other thread is all that uses the object, then you would temporarily cast it to shared or immutable, give it to the other thread, and then that thread would cast it back to thread-local to use it, and the original thread would have nothing to do with it any longer. On the other hand, if you're actively sharing an object across threads, then you cast it to shared and give it to the other thread. But then you have to use an appropriate thread-synchronization mechanism (likely a mutex in the case of a socket) to ensure that accessing the object is thread-safe. So, typically, you would lock a mutex to ensure that no other thread is accessing the object, and then you temporarily cast away shared while the object is protected by the mutex so that you can do whatever you need to do with the object, and once you're ready to release the mutex, you make sure that no thread-local references to the object remain before releasing the mutex. So, any code actually operating on the object would do so while it's typed as thread-local, and the compiler would complain if you accidentally accessed it through the shared referenc to the data (though the compiler doesn't currently catch all such cases - the -preview=nosharedaccess switch turns on more of the checks, and that's supposed to be become the default eventually, but it hasn't yet). In any case, you can freely cast between thread-local and shared. It's just that you need to be sure that when you do that, you're not violating the type system by having a thread-local reference to shared data access that shared data without first protecting it with a mutex. And that typically means not having any thread-local references to the shared data except when the mutex is locked. But if all you're doing is passing an object across threads, then it's pretty straightforward, since you just cast it to shared or immutable to be able to pass it across threads and then cast back to thread-local on the other side to use it as normal again (you just need to make sure that you don't leave a reference to the data on the original thread when you do that). - Jonathan M Davis