Ben_Craig

Biography

Comments

As Herb mentioned, there are basically two ways to deal with shared resources: put a lock around it (mutex), or give the resource "thread affinity" via something like a message queue. Neither one guarantees responsiveness, and if you want your program to clean up gracefully, both will have a "wait" at some point.

Basically, message queues don't guarantee responsiveness because one item in the queue could take a long time, and prevent the other items from being performed in a timely manner. In some applications, this shows up as a pause, followed by a rapid catch up as all the queued up events fire at once. This can be mitigated by splitting up your resources in a more fine grained manner, and putting the "slow" resources on their own threads. You can't just throw a thread pool at the problem though, as then you need to reintroduce mutexes.

As for the graceful cleanup, leaving threads running after main() exits is usually a bad idea. You can also run into problems if your application dynamically loads and unloads shared libraries, and you leave threads running that execute code in the unloaded library. Both of these cases are handled poorly by Herb's "stop message" implementation, at least if any of the messages are slow. You really want to be able to eject all existing items in the queue, and preferably signal the currently running item to stop. Not all apps need to clean up gracefully though.

Mostly off-topic, but is there any MSDN documentation on which STL algorithms can operate on movable types versus copyable types? In general, if an STL algorithm compiles on a type that is movable, but not copyable, does that mean that it is safe? Are there any known areas where msvc10 algorithms differs significantly from the C++11 standard in move vs. copy areas?

petke> STL> In theory, in the next platform / major binary breakage that Microsoft gets, they could change the name mangling scheme so that non-built in types include a CRC. This could detect a lot of binary breakers pretty easily. This would cause some amount of binary bloat (import and export tables would be larger), it wouldn't help for extern "C" interfaces, and it wouldn't help with COM like situations where clients just call non-exported virtual functions, but it would be something.

It would have to wait until a platform break, or be strictly opt-in though, because it does break binary. Maybe it could be tackled with some __declspec tags?

STL> I would have thought that _ITERATOR_DEBUG_LEVEL would have given itself a bit more room to grow. For example, SCL probably should be at 5, and HID at 10. This way values could have been set in between. One thing that I could see going in at less than 5 would be some /GS like modifications. Basically, vector and string could put some security cookies before and after their "real" allocation, and check those values during each deallocation of their memory range. That particular mitigation may not actually solve anything though, as an exploit may have already been run before a check ever happens.

@STL: Something I would like to see in future Advanced STL lectures would be a discussion of allocator trickiness, especially if you do any EBO (Empty Base Optimization) trickery. You may also want to discuss any special list::splice nastiness.

One other thing I am curious about... do the internal functions that take iterator tags get inlined to the point that no stack space is consumed by the tag instance? Basically, is that function call completely free, or does it cost you 1 byte on the stack in various places?