Hacker News new | past | comments | ask | show | jobs | submit login

I had this bug once about 10ish years ago when I was still a windows dev. Creating a 2nd window on a thread with a window already but then pumping it's main loop on a background thread can cause this. If you do that the loops get hooked to each other regardless of the thread pumping it. The child window has to wait until the parent window forwards the event for the second thread to pop it off. A mouse move will send a WM event and keep the child windows loop on the other thread spinning. My WM_TIMER on the child window was stuck as well.

It happened to me because I had a hidden window on the background thread to get WM events for USB disconnect and reconnect messages from the system. The bug report was funny. "Connecting USB data collection probe doesn't work unless the user moves the mouse after connecting." and the follow up bug "Data collection only works when moving the mouse."




The rule of thumb as I always heard it is that a window is "owned" by the thread that created it. You can send and post messages from a different thread, but do much else and you're asking for trouble. (And Send instead of Post is often problematic since it will block until the target thread processes it.)

Draining the message queue from a thread that doesn't own it makes absolutely no sense to me ... Does that actually work? Wouldn't you see the messages on the original thread's pump too? I thought the way it worked is each thread with ui objects has a queue, and SendMessage et al. will insert into the owning thread's queue. It took me a while to parse what you are saying, did you pass the hwnd into GetMessage from the other thread and that somehow convinced it to peek at another thread's queue?


COM hates MTA threading, most of the Office object model actually insists on STA single-threads sitting in the main UI thread to even work (i.e. you cannot use BackgroundWorker() )! Some guy @ MS even released this byzantine code to deal with the situation (http://blogs.msdn.com/b/andreww/archive/2008/11/19/implement...) which unfortunately doesn't work. It's completely nuts how bad the object model is.


As much as I make fun of java developers for over complicated solutions, I've never quite seen anything as over-engineered and byzantine as COM. I remember at my last job we had legacy COM objects that inherited from about 5-7 different templated objects, and that was... normal. COM is the worst.

I actually like windows as a user, but I'm amazed that it won as much developer mindshare as it did considering how much the win32 api sucks. It's brutal.


I think the core of COM is sound (pure interfaces, QI, refcounting, IDL).

I think the ugliness is due to threading issues and being welded on to Win32 message pumps. If you have a dedicated COM thread/pool you'll mostly be fine (security stuff can still get complicated). But on the other hand if you start doing COM things on a thread you own where you share control of the message pumping, you open yourself to a world of mental anguish.


I actually like COM. Sure there are historical accidents like STA. But if you are free of that legacy and keep it simple there are some nice features: reference counting, QueryInterface, consistent error codes across components, abstraction away from linking, not having to worry about which allocator an object uses. (Though last one is only important on Windows since different DLLs can end up using different heaps.)


COM doesnt mandate anything silly like that.


Similar to COM, are (beside OLE, DCOM, ActiveX) Gnome's "Bonobo" (component model) [1], KDE's KParts, Mozilla's XPCOM and CORBA.

Apple choose KHTML over Gecko for it's Webkit fork [2] because of the various cons of such component models.

[1] Bonobo is officially deprecated: http://en.wikipedia.org/wiki/Bonobo_(component_model)

[2] http://en.wikipedia.org/wiki/XPCOM


I remain convinced that C++ warps peoples minds into things like this :-). I'll go out on a limb and say that pretty much ALL of those things are horrible.


There are some advantages to COM, in that having a standard, somewhat introspectable notion of what an object is and what its lifetime is helped Firefox add cycle collection several years ago. (By contrast, leaks are harder to avoid in WebKit and Blink, because there is no cycle collector, at least until Blink lands Oilpan.)

I think COM's biggest sin was doing all this stuff without language support. It's just not sensible to graft interfaces and automatic memory management onto C without modifying the language. Objective-C is basically a slightly more duck typed COM, but it's not nearly as reviled because the object model is so deeply integrated into the language.


Pretty certain COM was designed with C in mind, maybe C++ as an after-thought. The differences between C++ objects and COM objects are severe enough to make it not really a lot of fun unless you limit yourself to C-like behaviors anyway (or use Microsoft's dandy language extensions to generate a crapload of boilerplate for you).


I've done COM in straight C and it's not too bad. It's rather reminiscent of the Linux kernel's "operations" struct-pointers. (i.e. where `struct file` contains a `struct file_operations *` and the operations struct itself is full of function pointers - kind of like the C++ vtable concept)


XPCOM is... yeah, it's pretty bad. Writing a Firefox plugin vs. writing a Chrome plugin is darkness vs. light.


Firefox has a new (well, it's at least a couple years old now) system that makes writing plugins not quite so painful:

https://developer.mozilla.org/en-US/docs/Jetpack


COM made several promises, and had it delivered on those promises, the world would be a better place. I can understand why projects tried to copy COM, only to regret it later.

As noted, GNOME deprecated Bonobo even though the GNOME name was meant to emphasize the CORBA/Bonobo aspect of things (Gnu Object Manipulation Environment). Mozilla spent a lot of effort removing gratuitous use of XPCOM ( https://wiki.mozilla.org/Gecko:DeCOMtamination ).


But COM has been adopted by Linux world too, and renamed to Bonobo. In fact, if you throw away all VB-specific stuff, COM and its C++ implementation is a great programming exercise and is imho quite elegant.


"The VB stuff" is pretty much all you get when you work with MS-Office.

Don't know that I'd call COM "elegant", but you could probably do worse for a language-agnostic object system. Funny enough, I never really "got" COM until I sat down and read up on Bonobo. Someone had a really accessible explanation for Monikers that would've saved me so much hair-pulling if I'd had anything similar for the Windows equivalent.


If you're calling an object living in STA, you should do it from the same thread or marshall the pointer before using it from a different thread. In the latter case the STA's thread needs to run message loop to process calls to the object. If the thread is showing a modal dialog or blocked doing a lengthy operation it doesn't happen. As you can see there is nothing wrong with the object model itself, it just allows to call an object that was designed to be single-threaded from the threads other than its "home" thread.


Pumping from the wrong thread is undefined behavior and it results in the bug above. It's a fairly common bug.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: