Chuck Messenger said: > William E. Kempf wrote: >> I don't follow what you're code is supposed to be doing. > > Background: I have a structure of information, 'mythread', of which I > need one per thread. That is, I've grouped all my tss variables into a > single structure. I need to "bootstrap" the main thread. Hence the > static variable initialization -- my thought (perhaps incorrect) being > that 'val' will be initialized before main() begins, thus bootstrapping > the main thread. I believe that's right -- that all static variables in > all translation units are initialized before main()...? > > (The point is that I don't have control of main() -- otherwise, I could > initialize current_thread in main(). This code is part of a library.) > >> 'val' always is >> assigned 0. Is it's only purpose to cause the call to init()? > > Yes.
OK, I've got some idea what you're doing now, but your comments still aren't gelling. >> Why would >> you want to do that in this manner? It seems to me the solution you >> need is as simple as: >> >> mythread *mythread_get() { >> mythread* t = *(current_thread.get()); >> if (t == 0) Sorry slight bug here: >> current_thread.reset(new mythread *); { t = new mythread *; current_thread.reset(t); } >> return t; >> } > > I was, perhaps misguidedly, trying to avoid the need to call a function > -- since I access the mythread structure alot. Ideally, I want as much > speed as the underlying OS-level implementation will allow. I still don't understand. Since the mythread structure has an instance per thread, you have to make a function call to get the current thread's instance no matter what. That's what the above does. Nothing else is done (well, there is a test and jump instruction, but do you need to optimize even that out!?!) unless this is our first call. I don't see how the init approach would be any more efficient, and would only work for the main thread. >> However, why thread_specific_ptr<mythread*>? My not just >> thread_specific_ptr<mythread>? This code doesn't look valid to me, >> but with out context I'm guessing. > > Because I don't want the 'mythread' structure to get deleted when the > thread dies. My understanding of tss is that part of the semantics is > that, if you do > > some_tss_value.reset(whatever); > > then when the thread ends, the thread library does 'delete whatever'. > Therefore, I'm forced to have tss store a pointer to mystruct*, rather > than mystruct* itself. Ahh... gotcha. You want the thread_specific_ptr<> in the thread_dev branch. >>>The problem is that I can't be sure, during init(), that >>> current_thread has been constructed. I believe that's at the root of >>> the bug I'm tracking. >>> >>>By contrast, in my pthread-specific code, I simply put the >>>pthread_key_create() call at the start of init(), thus ensuring proper >>> initialization order. But there's no analogous call I can make for a >>> thread_specific_ptr -- that call is done during construction time. >> >> >> pthread_key_create() only creates the key, it does not create any of >> the thread specific storage for which there'd be an initialization >> order issue. So, I don't understand what you're doing or what the >> problem is. > > The problem is that it is necessary for pthread_key_create() to be > called before I can set a value for it. Can I be sure that > thread_specific_ptr<mythread*> has been initialized before I try using > it during init()? I'm not that clear on C++ initialization order > semantics for statics. If I do: > > extern int i; > extern int j; > int j = i; > int i = j; > > then what happens? It isn't obvious to me how the order would be > established. And so, can I assume that the following is guaranteed to > work? No. > static SomeType var1; > static AnotherType var2 = var1.something(); > > That is, is var1 guaranteed to be constructed before I initialize var2 > from it? If they are in the same translation unit, yes. If not, no. With out fully understanding how you're using this, this sounds dicey. > The thing is: there is some sort of bug with (Boost Threads) TSS -- the > way I'm using it, that is. My attempts at tracking the bug failed, so I > resorted to replacing TSS with native pthreads, and that worked. The > only difference that I could glean between the TSS and pthreads versions > of my code were in init(). If I spent some more time on it, perhaps I > could definitively nail down this suspicion. > > So, as it is, I *suspect* that the problem is that "accessing a static > thread_specific_ptr<> during initialization of another static variable" > isn't guaranteed to work (because C++ doesn't, perhaps, define > initialization order for statics, so the thread_specific_ptr<> object > won't necessarily have been created by the time it is used). > > Assuming this is correct, then I'm proposing a new force_construction() > method for thread_specific_ptr<>, to ameliorate this kind of problem. > During thread_specific_ptr<>'s normal construction, it would detect > whether it had been "pre-constructed". Doesn't sound standards conforming to me, but maybe I'm not understanding what you're suggesting. However, there are standards conforming ways to get what I believe you want. In fact, what you're doing isn't really any different from what I do in the thread implementation in the thread_dev branch. Maybe you should look there for inspiration. If that doesn't help, let me know and I'll see if I can't do better for you. -- William E. Kempf _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost