mach port notifications

  • Hi,

    I'm trying to use mach ports on OSX as a signaling mechanism between
    unrelated tasks.  In particular, I'm using the mach ports to detect when
    a task terminates.  I've been able to do this successfully on OS X
    Server 1.2 as follows.  I have two tasks, A and B, where A is to monitor
    task B for task termination.  Task B creates and registers a mach port
    using the name server port:
           port_name_t        machport;

           ret = port_allocate(task_self(), &machport);
                     ret = netname_check_in(name_server_port, "foo",
    task_self(), machport);

    Task A creates a mach port to receive notifications and sets it as the
    notify port for the task:

    port_name_t  nport;

          ret = port_allocate(task_self(), &nport);
          task_set_special_port(task_self(), TASK_NOTIFY_PORT, nport);

    Then, task A acquires the port made available by task B and waits for a
    notification message:

        notification_t        notify;

        notify.notify_header.msg_local_port = nport;
        notify.notify_header.msg_size = sizeof(notification_t);
        ret = msg_receive(&notify.header, MSG_OPTION_NONE, 0);
        if ( (NOTIFY_PORT_DELETED == notify.notify_header.msg_id) ||
                        (NOTIFY_PORT_DESTROYED ==
    notify.notify_header.msg_id) )
          {
              fprintf(stderr, "Received port notif.\n");
          }

    However, I have not been able to port this to OS X.  I did find a
    posting on Omnigroup's mailing list that said that you should use the
    bootstrap_port instead of name_server_port.  I modified accordingly by
    using the bootstrap functions so that I can register and acquire a mach
    port.  But I haven't been able to figure out how to get notifications
    about the port being deleted or destroyed.  Any help is greatly
    appreciated.

    Thanks,

    Rob Aulwes
  • Check out mach_port_request_notification().

    Mach 3.0 has a much more flexible notification mechanism than Mach 2.5.
    So, instead of having a single notification port where all notifications
    for that task are directed, individual notifications can be sent to any
    port of your choosing.  The change was made because certain
    notifications (like no-more-sender notifications) must be sent to
    particular ports (in the no-more-senders case, to the same port they are
    about) in order to be interpreted correctly in multi-threaded servers.
    One other change is that the notifications carry references to the port
    name/rights in question.  Again, this change is for multi-threaded
    safety, but it means that the rights identified in the notification
    message must be released as well.

    In your specific case, the notification you are looking to request is a
    "dead-name" (MACH_NOTIFY_DEAD_NAME) notification.  That notification
    means that you (Task A) continues to hold a send right to a port whose
    receiver (Task B) went away.  You get an extra send right to the (now
    dead) port when this message is delivered.

    Other notifications you can request include:

    no-more-sender notifications (MACH_NOTIFY_NO_SENDERS).  This allows a
    receive right holder to get notified when the last send right to a port
    goes away.  This notification message does not carry and
    rights/references to the port in question.

    port-destroyed notifications (MACH_NOTIFY_PORT_DESTROYED).  These are
    trickier.  Basically, they are ways of saying "this port is very
    special" if anything ever tries to destroy the receive right for this
    port, send it back to me instead.  This notification message carries the
    receive right for the port in question.

    In addition to the successful delivery of dead-name, port-destroyed, and
    no-more-senders notifications, the notification subsystem may deliver
    one of the following notification messages:

    port-deleted notification messages.  Some other logic in your task
    deleted the name that you had an outstanding notification request
    against.  Essentially, this is the notification mechanism's way of
    informing you that the notification request is being cancelled.  You
    don't request these notifications explicitly, they come as a response to
    other notifications.  This notification does not carry any
    rights/references for the port in question.

    send-once notification messages.  In Mach 3.0, there is the concept of a
    send-once right.  It gives the right to send only one (and exactly one)
    message to a port.  It is used extensively by MIG for RPC reply port
    rights.  If the sender deallocates the send-once right before using it
    (explicitly, or through unexpected termination), the IPC system will
    send a send-once notification to the target port in lieu of an actual
    message from the client.  It makes error recovery from
    "never-going-to-complete" RPCs much simpler. This notification does not
    carry any rights/references for the target port.

    Hope this helps some,
    --Jim

    On Friday, September 21, 2001, at 01:46 PM, Rob Aulwes wrote:

    > Task A creates a mach port to receive notifications and sets it as the
    > notify port for the task:
    >
    > port_name_t        nport;
    >
    > ret = port_allocate(task_self(), &nport);
    > task_set_special_port(task_self(), TASK_NOTIFY_PORT, nport);
    >
    > Then, task A acquires the port made available by task B and waits for a
    > notification message:
    >
    > notification_t        notify;
    >
    > notify.notify_header.msg_local_port = nport;
    > notify.notify_header.msg_size = sizeof(notification_t);
    > ret = msg_receive(&notify.header, MSG_OPTION_NONE, 0);
    > if ( (NOTIFY_PORT_DELETED == notify.notify_header.msg_id) ||
    > (NOTIFY_PORT_DESTROYED ==
    > notify.notify_header.msg_id) )
    > {
    > fprintf(stderr, "Received port notif.\n");
    > }
    >
    >
    > However, I have not been able to port this to OS X.  I did find a
    > posting on Omnigroup's mailing list that said that you should use the
    > bootstrap_port instead of name_server_port.  I modified accordingly by
    > using the bootstrap functions so that I can register and acquire a mach
    > port.  But I haven't been able to figure out how to get notifications
    > about the port being deleted or destroyed.  Any help is greatly
    > appreciated.
    >
    > Thanks,
    >
    > Rob Aulwes
    >
    > _______________________________________________
    > MacOSX-dev mailing list
    > <MacOSX-dev...>
    > http://www.omnigroup.com/mailman/listinfo/macosx-dev
    >
  • Sorry for the delay, this got stuck as undeliverable and I acutally took
    a weekend off.

    As others have said: Check out mach_port_request_notification().

    Mach 3.0 has a much more flexible notification mechanism than Mach 2.5.
    So, instead of having a single notification port where all notifications
    for that task are directed, individual notifications can be sent to any
    port of your choosing.  The change was made because certain
    notifications (like no-more-sender notifications) must be sent to
    particular ports (in the no-more-senders case, to the same port they are
    about) in order to be interpreted correctly in multi-threaded servers.
    One other change is that the notifications carry references to the port
    name/rights in question.  Again, this change is for multi-threaded
    safety, but it means that the rights identified in the notification
    message must be released as well.

    In your specific case, the notification you are looking to request is a
    "dead-name" (MACH_NOTIFY_DEAD_NAME) notification.  That notification
    means that you (Task A) continues to hold a send right to a port whose
    receiver (Task B) went away.  You get an extra send right to the (now
    dead) port when this message is delivered (so your handler for this
    notification message will likely have to release 2 send rights, the
    original one you held and the one delivered in the notification).

    Other notifications you can request include:

    no-more-sender notifications (MACH_NOTIFY_NO_SENDERS).  This allows a
    receive right holder to get notified when the last send right to a port
    goes away.  This notification message does not carry and
    rights/references to the port in question.

    port-destroyed notifications (MACH_NOTIFY_PORT_DESTROYED).  These are
    trickier.  Basically, they are ways of saying "this port is very
    special" if anything ever tries to destroy the receive right for this
    port, send it back to me instead.  This notification message carries the
    receive right for the port in question.

    In addition to the successful delivery of dead-name, no-more-senders,
    and port-destroyed notifications, the mach port notification subsystem
    may deliver one of the following notification messages:

    port-deleted notification messages.  Some other logic in your task
    deleted the name that you had an outstanding notification request
    against.  Essentially, this is the notification mechanism's way of
    informing you that the notification request is being cancelled.  You
    don't request these notifications explicitly, they come as a response to
    other notifications.  This notification does not carry any
    rights/references for the port in question.

    send-once notification messages.  In Mach 3.0, there is the concept of a
    send-once right.  It gives the right to send only one (and exactly one)
    message to a port.  It is used extensively by MIG for RPC reply port
    rights.  If the sender deallocates the send-once right before using it
    (explicitly, or through unexpected termination), the IPC system will
    send a send-once notification to the target port in lieu of an actual
    message from the client.  It makes error recovery from
    "never-going-to-complete" RPCs much simpler. This notification does not
    carry any rights/references for the target port.

    Hope this helps some,
    --Jim

    On Friday, September 21, 2001, at 01:46 PM, Rob Aulwes wrote:

    > Task A creates a mach port to receive notifications and sets it as the
    > notify port for the task:
    >
    > port_name_t        nport;
    >
    > ret = port_allocate(task_self(), &nport);
    > task_set_special_port(task_self(), TASK_NOTIFY_PORT, nport);
    >
    > Then, task A acquires the port made available by task B and waits for a
    > notification message:
    >
    > notification_t        notify;
    >
    > notify.notify_header.msg_local_port = nport;
    > notify.notify_header.msg_size = sizeof(notification_t);
    > ret = msg_receive(&notify.header, MSG_OPTION_NONE, 0);
    > if ( (NOTIFY_PORT_DELETED == notify.notify_header.msg_id) ||
    > (NOTIFY_PORT_DESTROYED ==
    > notify.notify_header.msg_id) )
    > {
    > fprintf(stderr, "Received port notif.\n");
    > }
    >
    >
    > However, I have not been able to port this to OS X.  I did find a
    > posting on Omnigroup's mailing list that said that you should use the
    > bootstrap_port instead of name_server_port.  I modified accordingly by
    > using the bootstrap functions so that I can register and acquire a mach
    > port.  But I haven't been able to figure out how to get notifications
    > about the port being deleted or destroyed.  Any help is greatly
    > appreciated.
    >
    > Thanks,
    >
    > Rob Aulwes
    >
    > _______________________________________________
    > MacOSX-dev mailing list
    > <MacOSX-dev...>
    > http://www.omnigroup.com/mailman/listinfo/macosx-dev
    >
  • Until someone who knows what they're talking about shows up, you
    might check out the 'mach_init' subproject of the system_cmds
    project (in the Darwin repository).  There're an alarming number of
    references there to bootstrap_port.

    Regards,

    Justin

    On Friday, September 21, 2001, at 01:46 PM, Rob Aulwes wrote:

    > Hi,
    >
    > I'm trying to use mach ports on OSX as a signaling mechanism
    > between unrelated tasks.  In particular, I'm using the mach ports
    > to detect when a task terminates.  I've been able to do this
    > successfully on OS X Server 1.2 as follows.  I have two tasks, A
    > and B, where A is to monitor task B for task termination.  Task B
    > creates and registers a mach port using the name server port:
    > port_name_t        machport;
    >
    > ret = port_allocate(task_self(), &machport);
    > ret = netname_check_in(name_server_port, "foo",
    > task_self(), machport);
    >
    > Task A creates a mach port to receive notifications and sets it as
    > the notify port for the task:
    >
    > port_name_t        nport;
    >
    > ret = port_allocate(task_self(), &nport);
    > task_set_special_port(task_self(), TASK_NOTIFY_PORT, nport);
    >
    > Then, task A acquires the port made available by task B and waits
    > for a notification message:
    >
    > notification_t        notify;
    >
    > notify.notify_header.msg_local_port = nport;
    > notify.notify_header.msg_size = sizeof(notification_t);
    > ret = msg_receive(&notify.header, MSG_OPTION_NONE, 0);
    > if ( (NOTIFY_PORT_DELETED == notify.notify_header.msg_id) ||
    > (NOTIFY_PORT_DESTROYED ==
    > notify.notify_header.msg_id) )
    > {
    > fprintf(stderr, "Received port notif.\n");
    > }
    >
    >
    > However, I have not been able to port this to OS X.  I did find a
    > posting on Omnigroup's mailing list that said that you should use
    > the bootstrap_port instead of name_server_port.  I modified
    > accordingly by using the bootstrap functions so that I can
    > register and acquire a mach port.  But I haven't been able to
    > figure out how to get notifications about the port being deleted
    > or destroyed.  Any help is greatly appreciated.
    >
    > Thanks,
    >
    > Rob Aulwes
    > _______________________________________________
    > darwin-development mailing list
    > <darwin-development...>
    > http://www.lists.apple.com/mailman/listinfo/darwin-development

    ---
    Justin C. Walker, Curmudgeon-At-Large  *
    Institute for General Semantics        |
    Director of Technology                | It's not whether you win
    or lose...
    Nexsi Systems Corp.                    |  It's whether *I* win or lose.
    1959 Concourse Drive                  |
    San Jose, CA  95131                    |
    *--------------------------------------*-------------------------------*
  • The relevant bits are in /usr/include/mach/mach/notify.h, but its
    basically...

    mach_port_request_notification(mach_task_self(),port_thats_gonna_die,MACH_NOTIFY_DEAD_NAME,
    0,port_to_receive_notification,MACH_MSG_TYPE_MAKE_SEND_ONCE,&old_port_to_receive_notification)
    ;

    -Ed

    On Saturday, September 22, 2001, at 05:45  PM, Justin C. Walker wrote:

    > Until someone who knows what they're talking about shows up, you might
    > check out the 'mach_init' subproject of the system_cmds project (in the
    > Darwin repository).  There're an alarming number of references there to
    > bootstrap_port.
    >
    > Regards,
    >
    > Justin
    >
    > On Friday, September 21, 2001, at 01:46 PM, Rob Aulwes wrote:
    >
    >> Hi,
    >>
    >> I'm trying to use mach ports on OSX as a signaling mechanism between
    >> unrelated tasks.  In particular, I'm using the mach ports to detect
    >> when a task terminates.  I've been able to do this successfully on OS
    >> X Server 1.2 as follows.  I have two tasks, A and B, where A is to
    >> monitor task B for task termination.  Task B creates and registers a
    >> mach port using the name server port:
    >> port_name_t        machport;
    >>
    >> ret = port_allocate(task_self(), &machport);
    >> ret = netname_check_in(name_server_port, "foo",
    >> task_self(), machport);
    >>
    >> Task A creates a mach port to receive notifications and sets it as the
    >> notify port for the task:
    >>
    >> port_name_t        nport;
    >>
    >> ret = port_allocate(task_self(), &nport);
    >> task_set_special_port(task_self(), TASK_NOTIFY_PORT, nport);
    >>
    >> Then, task A acquires the port made available by task B and waits for
    >> a notification message:
    >>
    >> notification_t        notify;
    >>
    >> notify.notify_header.msg_local_port = nport;
    >> notify.notify_header.msg_size = sizeof(notification_t);
    >> ret = msg_receive(&notify.header, MSG_OPTION_NONE, 0);
    >> if ( (NOTIFY_PORT_DELETED == notify.notify_header.msg_id) ||
    >> (NOTIFY_PORT_DESTROYED ==
    >> notify.notify_header.msg_id) )
    >> {
    >> fprintf(stderr, "Received port notif.\n");
    >> }
    >>
    >>
    >> However, I have not been able to port this to OS X.  I did find a
    >> posting on Omnigroup's mailing list that said that you should use the
    >> bootstrap_port instead of name_server_port.  I modified accordingly by
    >> using the bootstrap functions so that I can register and acquire a
    >> mach port.  But I haven't been able to figure out how to get
    >> notifications about the port being deleted or destroyed.  Any help is
    >> greatly appreciated.
    >>
    >> Thanks,
    >>
    >> Rob Aulwes
    >> _______________________________________________
    >> darwin-development mailing list
    >> <darwin-development...>
    >> http://www.lists.apple.com/mailman/listinfo/darwin-development
    >
    > ---
    > Justin C. Walker, Curmudgeon-At-Large  *
    > Institute for General Semantics        |
    > Director of Technology                | It's not whether you win or
    > lose...
    > Nexsi Systems Corp.                    |  It's whether *I* win or lose.
    > 1959 Concourse Drive                  |
    > San Jose, CA  95131                    |
    > *--------------------------------------*-------------------------------*
    > _______________________________________________
    > darwin-development mailing list
    > <darwin-development...>
    > http://www.lists.apple.com/mailman/listinfo/darwin-development
  • CoreFoundation is another example of source code in Darwin which does
    this.  See the sources for CFMachPort.c.  However, it monitors the "port
    to be notified" via the run loop, so you will have to write the
    mach_msg(RCV) part yourself (unless you could use CF), and of course
    ignore all the things CFMachPort does that you don't need.

    Chris Kane
    Cocoa Frameworks, Apple

    On Saturday, September 22, 2001, at 02:45  PM, Justin C. Walker wrote:

    > Until someone who knows what they're talking about shows up, you might
    > check out the 'mach_init' subproject of the system_cmds project (in the
    > Darwin repository).  There're an alarming number of references there to
    > bootstrap_port.
    >
    > Regards,
    >
    > Justin
    >
    > On Friday, September 21, 2001, at 01:46 PM, Rob Aulwes wrote:
    >
    >> Hi,
    >>
    >> I'm trying to use mach ports on OSX as a signaling mechanism between
    >> unrelated tasks.  In particular, I'm using the mach ports to detect
    >> when a task terminates.  I've been able to do this successfully on OS
    >> X Server 1.2 as follows.  I have two tasks, A and B, where A is to
    >> monitor task B for task termination.  Task B creates and registers a
    >> mach port using the name server port:
    >> port_name_t        machport;
    >>
    >> ret = port_allocate(task_self(), &machport);
    >> ret = netname_check_in(name_server_port, "foo",
    >> task_self(), machport);
    >>
    >> Task A creates a mach port to receive notifications and sets it as the
    >> notify port for the task:
    >>
    >> port_name_t        nport;
    >>
    >> ret = port_allocate(task_self(), &nport);
    >> task_set_special_port(task_self(), TASK_NOTIFY_PORT, nport);
    >>
    >> Then, task A acquires the port made available by task B and waits for
    >> a notification message:
    >>
    >> notification_t        notify;
    >>
    >> notify.notify_header.msg_local_port = nport;
    >> notify.notify_header.msg_size = sizeof(notification_t);
    >> ret = msg_receive(&notify.header, MSG_OPTION_NONE, 0);
    >> if ( (NOTIFY_PORT_DELETED == notify.notify_header.msg_id) ||
    >> (NOTIFY_PORT_DESTROYED ==
    >> notify.notify_header.msg_id) )
    >> {
    >> fprintf(stderr, "Received port notif.\n");
    >> }
    >>
    >>
    >> However, I have not been able to port this to OS X.  I did find a
    >> posting on Omnigroup's mailing list that said that you should use the
    >> bootstrap_port instead of name_server_port.  I modified accordingly by
    >> using the bootstrap functions so that I can register and acquire a
    >> mach port.  But I haven't been able to figure out how to get
    >> notifications about the port being deleted or destroyed.  Any help is
    >> greatly appreciated.
    >>
    >> Thanks,
    >>
    >> Rob Aulwes
    >> _______________________________________________
    >> darwin-development mailing list
    >> <darwin-development...>
    >> http://www.lists.apple.com/mailman/listinfo/darwin-development
    >
    > ---
    > Justin C. Walker, Curmudgeon-At-Large  *
    > Institute for General Semantics        |
    > Director of Technology                | It's not whether you win or
    > lose...
    > Nexsi Systems Corp.                    |  It's whether *I* win or lose.
    > 1959 Concourse Drive                  |
    > San Jose, CA  95131                    |
    > *--------------------------------------*-------------------------------*
    > _______________________________________________
    > MacOSX-dev mailing list
    > <MacOSX-dev...>
    > http://www.omnigroup.com/mailman/listinfo/macosx-dev
previous month september 2001 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today
MindNode
MindNode offered a free license !