mach_thread_self()
implies adding aMACH_PORT_RIGHT_SEND
on the thread port. It must be followed with a matchingmach_port_deallocate
call when the reference is no longer needed.
- Mach messages received from the kernel after registering with
thread_swap_exception_ports
may contain Mach ports, depending on the flavor of message. Any such ports must be deallocated by the receiver. If you pass the message along, then you can get away with just transferring ownership along as well, presuming that the next mach port in the chain wants a sufficiently similar flavor of exception message as you do.
Although I was able to use the dtrace example earlier to do some early diagnostics, since
mach_port_allocate
was not the only generator of Mach ports in the process (e.g., the kernel when sending us exception messages), it was not sufficient. Instead, I ended up using Apple’s own sample, MachPortDump, in combination with some strategically placed breakpoints in gdb to try and narrow down when the ports were coming into existence, and what the ports actually were.2It really is too bad that Apple deems these APIs to be unworthy of documenting. Admittedly, only a few developers really need to get down into this nitty-gritty, but if the only choices are reading the 17-year-old Programming Under Mach whose API references are out-of-date and whose code samples don’t deallocate these ports either, reading the darwin source (not an option for me), pestering ADC, or stumbling around in the dark, I can wager what will happen, and what the quality of the resulting products will be on the OS. Perhaps the consumers will lay the blame at the application developer’s feet, or at Apple’s, or both. In any case, it makes it hard to do things the right way, which I’m pretty sure we all want. (Or at least want slightly more than doing it the wrong way — not doing it at all isn’t an option.)
----
1What does happen when you wrap the refcount number on a Mach port? Hm…
2MachPortDump just lists what ports are in the process and what kind/rights it has, not what the port is related to. You have to be a little creative to figure out what the port being incremented belongs to, e.g.,
(mach_port_t)pthread_mach_thread_np((pthread_t)pthread_self())
to figure out what the current thread’s port is. AFAICT, there’s no Mac OS X analog to netmsgserver
to annotate ports.
3 comments:
I have this problem, but can't figure out how to call mach_port_deallocate(). Do you have an example? mach_port_deallocate() isn't defined by the same include files, isn't documented as taking thread_t (does that inherit from mach_port_name_t?) and it has another parameter. What's an ipc_space_t? Examples I've seen get it from mach_task_self (what is a task?), but that is documented as increasing the refcount on yet another port, which just moves the problem.
I'm lost in all this Mach jargon.
mach_port_deallocate is defined in /usr/include/mach/mach_port.h, generated from mach_port.defs in the same directory. The task can be retrieved with mach_task_self(), presuming you're operating on the currently running executable. mach_task_self() doesn't increment the refcount on the task port it returns, AFAICT. Even if it did, you could cache the value of mach_task_self(), use it to free the other port, and then use it to free itself.
The short form is that task is an instance of an application. I think that theoretically you could have multiple tasks in one application, but I have never seen it.
Thanks, I will give that a try.
(By the way, that's not my real hair, that's fake hair attached to the hat.)
Post a Comment