door_xcreate(3c) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

door_xcreate(3c)

Standard C Library Functions                                  door_xcreate(3C)



NAME
       door_xcreate  -  create  a door descriptor for a private door with per-
       door control over thread creation

SYNOPSIS
       #include <door.h>

       typedef void door_server_procedure_t(void *, char *, size_t,
            door_desc_t *, uint_t);


       typedef int door_xcreate_server_func_t(door_info_t *,
            void *(*)(void *), void *, void *);


       typedef void door_xcreate_thrsetup_func_t(void *);


       int door_xcreate(door_server_procedure_t *server_procedure,
            void *cookie, uint_t attributes,
            door_xcreate_server_func_t *thr_create_func,
            door_xcreate_thrsetup_func_t *thr_setup_func, void *crcookie,
            int nthread);

DESCRIPTION
       The door_xcreate()  function  creates  a  private  door  to  the  given
       server_procedure,  with  per-door  control over the creation of threads
       that will service invocations of that door. A private door  is  a  door
       that  has  a  private  pool  of threads that service calls to that door
       alone; non-private doors share a pool of service threads (see door_cre‐
       ate(3C)).

   Creating private doors using door_create()
       Prior to the introduction of door_xcreate(), a private door was created
       using door_create() specifying attributes including DOOR_PRIVATE  after
       installing  a  suitable  door  server  thread  creation  function using
       door_server_create(). During such a call to  door_create(),  the  first
       server thread for that door is created by calling the door server func‐
       tion; you must therefore already have installed a  custom  door  server
       creation  function  using  door_server_create(). The custom server cre‐
       ation function is called at initial creation of  a  private  door,  and
       again whenever a new invocation uses the last available thread for that
       door. The function must decide whether it wants to increase  the  level
       of  concurrency by creating an additional thread - if it decides not to
       then further invocations may have to wait for an existing active  invo‐
       cation  to  complete before they can proceed. Additional threads may be
       created using whatever thread attributes are desired  in  the  applica‐
       tion,  and  the  application  must  specify a thread start function (to
       thr_create(3C) or pthread_create(3C)) which will perform a  door_bind()
       to  the newly-created door before calling door_return(NULL, 0, NULL, 0)
       to enter service. See door_server_create(3C) and door_bind(3C) for more
       information and for an example.


       This  "legacy" private door API is adequate for many uses, but has some
       limitations:

           o      The  server  thread  creation  function  appointed  via  the
                  door_server_create()  is shared by all doors in the process.
                  Private doors are distinguished from non-private in that the
                  door_info_t pointer argument to the thread creation function
                  is non-null for private  doors;  from  the  door_info_t  the
                  associated  door  server  procedure  is  available  via  the
                  di_proc member.


           o      If a library wishes to create a private door  of  which  the
                  application  is  essentially unaware it has no option but to
                  inherit any  function  appointed  with  door_server_create()
                  which may render the library door inoperable.


           o      Newly-created server threads must bind to the door they will
                  service,  but  the  door  file  descriptor   to   quote   in
                  door_bind() is not available in the door_info_t structure we
                  receive a pointer to. The door file descriptor  is  returned
                  as  the  result  of  door_create(),  but the initial service
                  thread is created during the  call  to  door_create().  This
                  leads  to  complexity  in the startup of the service thread,
                  and tends to force the use of global variables for the  door
                  file descriptors as per the example in door_bind().


   Creating private doors with door_xcreate()
       The  door_xcreate()  function  is  purpose-designed for the creation of
       private doors and simplifies their use  by  moving  responsibility  for
       binding the new server thread and synchronizing with it into a library-
       provided thread startup function:

           o      The first three arguments to door_xcreate() are as you would
                  use  in  door_create(): the door server_procedure, a private
                  cookie to pass to that procedure whenever it is invoked  for
                  this  door,  and  desired  door attributes. The DOOR_PRIVATE
                  attribute  is  implicit,  and  an  additional  attribute  of
                  DOOR_NO_DEPLETION_CB is available.


           o      Four  additional  arguments specify a server thread creation
                  function to use for this door (must not be NULL),  a  thread
                  setup  function  for  new  server  threads  (can be NULL), a
                  cookie to pass to those functions, and the initial number of
                  threads to create for this door.


           o      The door_xcreate_server_func_t() for creating server threads
                  has differing semantics to those of  a  door_server_func_t()
                  used  in  door_server_create(). In addition to a door_info_t
                  pointer it also receives  as  arguments  a  library-provided
                  thread start function and thread start argument that it must
                  use, and the  private  cookie  registered  in  the  call  to
                  door_xcreate().  The  nominated door_xcreate_server_func_t()
                  must:


               o      Return 0 if no additional thread is to be  created,  for
                      example  if  it decides the current level of concurrency
                      is sufficient. When the server thread creation  function
                      is  invoked  as part of a depletion callback (as opposed
                      to  during  initial  door_xcreate())   the   door_info_t
                      di_attributes member includes DOOR_DEPLETION_CB.


               o      Otherwise attempt to create exactly one new thread using
                      thr_create() or pthread_create(), with  whatever  thread
                      attributes  (stack  size)  are  desired  and quoting the
                      implementation-provided thread start function and opaque
                      data cookie. If the call to thr_create() or pthread_cre‐
                      ate() is successful then return 1, otherwise return -1.


               o      Do not call door_bind() or request to enter service  via
                      door_return(NULL, 0, NULL, 0).

           As  in  door_server_create()  new  server  threads  must be created
           PTHREAD_SCOPE_SYSTEM and PTHREAD_CREATE_DETACHED for POSIX threads,
           and THR_BOUND and THR_DETACHED for Solaris threads. The signal dis‐
           position and scheduling class of newly-created threads  are  inher‐
           ited  from  the  calling  thread, initially from the thread calling
           door_xcreate() and subsequently from the current active door server
           thread.


           o      The library-provided thread start function performs the fol‐
                  lowing operations in the order presented:

               o      Calls the door_xcreate_thrsetup_func_t() if  it  is  not
                      NULL, passing the crcookie. You can use this setup func‐
                      tion to perform custom service thread configuration that
                      must  be  done from the context of the new thread. Typi‐
                      cally this is to configure cancellation preferences, and
                      possibly  to  associate application thread-specific-data
                      with the newly-created server thread.

                      If thr_setup_func() was NULL then a default  is  applied
                      which  will  configure  the new thread with pthread_set‐
                      cancelstate(PTHREAD_CANCEL_DISABLE,      NULL)       and
                      pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL). If
                      the server code is truly interested in notifications  of
                      client  aborts  during  a  door invocation then you will
                      need to provide a thr_setup_func() that does not disable
                      cancellations,   and  use  pthread_cleanup_push(3C)  and
                      pthread_cleanup_pop(3C) as appropriate.


               o      Binds the new thread to the door file  descriptor  using
                      door_bind().


               o      Synchronizes  with door_xcreate() so that the new server
                      thread  is  known   to   have   successfully   completed
                      door_bind() before door_xcreate() returns.



           o      The number of service threads to create at initial door cre‐
                  ation time can be controlled through the nthread argument to
                  door_xcreate().  The  nominated door_xcreate_server_func_t()
                  will be called nthread times. All nthread new server threads
                  must  be  created  successfully (thr_create_func() returns 1
                  for each) and all must succeed in binding to the  new  door;
                  if  fewer  than  nthread  threads are created, or fewer than
                  nthread succeed in binding, then  door_xcreate()  fails  and
                  any threads that were created are made to exit.

                  No  artificial maximum value is imposed on the nthread argu‐
                  ment: it may be as high as system  resources  and  available
                  virtual memory permit. There is a small amount of additional
                  stack usage in  the  door_xcreate()  stack  frame  for  each
                  thread - up to 16 bytes in a 64-bit application. If there is
                  insufficient room to extend the stack for this purpose  then
                  door_xcreate() fails with E2BIG.

                  The  door  attributes  that  can  be selected in the call to
                  door_xcreate()  are  the  same  as  in  door_create(),  with
                  DOOR_PRIVATE implied and DOOR_NO_DEPLETION_CB added:

                  DOOR_PRIVATE

                      It  is  not  necessary  to  include  this attribute. The
                      door_xcreate() interfaces only creates private doors.


                  DOOR_NO_DEPLETION_CB

                      Create the initial pool of nthread service threads,  but
                      do   not  perform  further  callbacks  to  the  thr_cre‐
                      ate_func() for this door when the thread pool appears to
                      be  depleted at the start of a new door invocation. This
                      allows you to select a fixed level of concurrency.

                      Another di_attribute is defined during thread  depletion
                      callbacks:


                  DOOR_DEPLETION_CB

                      This  call to the server thread creation function is the
                      result of a depletion callback. This  attribute  is  not
                      set   when   the   function  is  called  during  initial
                      door_xcreate().




       The descriptor returned from door_xcreate() will be marked as close  on
       exec  (FD_CLOEXEC).  Information  about  a  door  is  available for all
       clients of a door  using  door_info(3C).  Applications  concerned  with
       security  should  not  place  secure  information  in door data that is
       accessible by door_info(). In particular, secure  data  should  not  be
       stored in the data item cookie.


       A process can advertise a door in the file system name space using fat‐
       tach(3C).


       After creation, door_setparam(3C) can be used  to  set  limits  on  the
       amount of data and descriptors clients can send over the door.


       A   door   created   with   door_xcreate()   may   be   revoked   using
       door_revoke(3C). This closes the associated file descriptor,  and  acts
       as  a  barrier to further door invocations, but existing active invoca‐
       tions  are  not  guaranteed  to  have  completed  before  door_revoke()
       returns.  Server  threads bound to a revoked door do not wakeup or exit
       automatically when the door is revoked.

RETURN VALUES
       Upon  successful  completion,  door_xcreate()  returns  a  non-negative
       value.  Otherwise, door_xcreate() returns -1 and sets errno to indicate
       the error.

ERRORS
       The door_xcreate() function will fail if:

       E2BIG      The requested nthread is too large. A small amount of  stack
                  space is required for each thread we must start and synchro‐
                  nize with. If extending  the  door_xcreate()  stack  by  the
                  required  amount  will exceed the stack bounds then E2BIG is
                  returned.


       EBADF      The  attempt  to  door_bind()  within  the  library-provided
                  thread start function failed.


       EINVAL     Invalid  attributes  are  passed, nthread is less than 1, or
                  thr_create_func() is NULL. This is also returned if thr_cre‐
                  ate_func()  returns  0 (no thread creation attempted) during
                  door_xcreate().


       EMFILE     The process has too many open descriptors.


       ENOMEM     Insufficient memory condition while creating the door.


       ENOTSUP    A door_xcreate() call was attempted from a fork handler.


       EPIPE      A call to the nominated thr_create_func() returned -1  indi‐
                  cating that pthread_create() or thr_create() failed.


EXAMPLES
       Example  1  Create  a  private  door  with an initial pool of 10 server
       threads



       Create a private door with  an  initial  pool  of  10  server  threads.
       Threads  are  created with the minimum required attributes and there is
       no thread setup function. Use fattach() to advertise the  door  in  the
       filesystem namespace.


         static pthread_attr_t tattr;

         /*
          * Simplest possible door_xcreate_server_func_t.  Always attempt to
          * create a thread, using the previously initialized attributes for
          * all threads. We must use the start function and argument provided,
          * and make no use of our private mycookie argument.
          */
         int
         thrcreatefunc(door_info_t *dip, void *(*startf)(void *),
             void *startfarg, void *mycookie)
         {
                 if (pthread_create(NULL, &tattr, startf, startfarg) != 0) {
                         perror("thrcreatefunc: pthread_create");
                         return (-1);
                 }

                 return (1);
         }

         /*
          * Dummy door server procedure - does no processing.
          */
         void
         door_proc(void *cookie, char *argp, size_t argsz, door_desc_t *descp,
             uint_t n)
         {
             door_return (NULL, 0, NULL, 0);
         }

         int
         main(int argc, char *argv[])
         {
             struct stat buf;
             int did;

             /*
              * Setup thread attributes - minimum required.
              */
             (void) pthread_attr_init(&tattr);
             (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
             (void) pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);

             /*
              * Create a private door with an initial pool of 10 server threads.
              */
             did = door_xcreate(door_proc, NULL, 0, thrcreatefunc, NULL, NULL,
                                10);

             if (did == -1) {
                 perror("door_xcreate");
                 exit(1);
             }

             if (stat(DOORPATH, &buf) < 0) {
                 int newfd;

                 if ((newfd = creat(DOORPATH, 0644)) < 0) {
                     perror("creat");
                     exit(1);
                 }
                 (void) close(newfd);
             }

             (void) fdetach(DOORPATH);

             (void) fdetach(DOORPATH);
             if (fattach(did, DOORPATH) < 0) {
                 perror("fattach");
                 exit(1);
             }

             (void) fprintf(stderr, "Pausing in main\n");
             (void) pause();
         }





       Example  2  Create a private door with exactly one server thread and no
       callbacks for additional threads



       Create a private door with exactly one server thread and  no  callbacks
       for additional threads. Use a server thread stacksize of 32K, and spec‐
       ify a thread setup function.


         #define DOORPATH        "/tmp/grmdoor"

         static pthread_attr_t tattr;

         /*
          * Thread setup function - configuration that must be performed from
          * the context of the new thread.  The mycookie argument is the
          * second-to-last argument from door_xcreate.
          */
         void
         thrsetupfunc(void *mycookie)
         {
             /*
              * If a thread setup function is specified it must do the
              * following at minimum.
              */
             (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

             /*
              * The default thread setup functions also performs the following
              * to disable thread cancellation notifications, so that server
              * threads are not cancelled when a client aborts a door call.
              * This is not a requirement.
              */
             (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

             /*
              * Now we can go on to perform other thread initialization,
              * for example to allocate and initialize some thread-specific data
              * for this thread;  for thread-specific data you can use a
                destructor function in pthread_key_create if you want to perform
                any actions if/when a door server thread exits.
              */
         }

         /*
          * The door_xcreate_server_func_t we will use for server thread
          * creation. The mycookie argument is the second-to-last argument
          * from door_xcreate.
          */
         int
         thrcreatefunc(door_info_t *dip, void *(*startf)(void *),
             void *startfarg, void *mycookie)
         {
             if (pthread_create(NULL, &tattr, startf, startfarg) != 0) {
                     perror("thrcreatefunc: pthread_create");
                     return (-1);
             }

             return (1);
         }

         /*
          * Door procedure.  The cookie received here is the second arg to
          * door_xcreate.
          */
         void
         door_proc(void *cookie, char *argp, size_t argsz, door_desc_t *descp,
             uint_t n)
         {
             (void) door_return(NULL, 0, NULL, 0);
         }

         int
         main(int argc, char *argv[])
         {
             struct stat buf;
             int did;

             /*
              * Configure thread attributes we will use in thrcreatefunc.
              * The PTHREAD_CREATE_DETACHED and PTHREAD_SCOPE_SYSTEM are
              * required.
              */
             (void) pthread_attr_init(&tattr);
             (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
             (void) pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
             (void) pthread_attr_setstacksize(&tattr, 16 * 1024);

             /*
              * Create a private door with just one server thread and asking for
                  * no further callbacks on thread pool depletion during an
                  * invocation.
                  */
             did = door_xcreate(door_proc, NULL, DOOR_NO_DEPLETION_CB,
                 thrcreatefunc, thrsetupfunc, NULL, 1);

             if (did == -1) {
                     perror("door_xcreate");
                     exit(1);
             }

             if (stat(DOORPATH, &buf) < 0) {
                     int newfd;

                     if ((newfd = creat(DOORPATH, 0644)) < 0) {
                             perror("creat");
                             exit(1);
                     }
                     (void) close(newfd);
             }

             (void) fdetach(DOORPATH);
             if (fattach(did, DOORPATH) < 0) {
                     perror("fattach");
                     exit(1);
             }

             (void) fprintf(stderr, "Pausing in main\n");
             (void) pause();
         }





ATTRIBUTES
       See attributes(7) for descriptions of the following attributes:


       tab() box; cw(2.75i) |cw(2.75i) lw(2.75i) |lw(2.75i) ATTRIBUTE  TYPEAT‐
       TRIBUTE  VALUE  _ Architectureall _ Availabilitysystem/core-os _ Inter‐
       face StabilityCommitted _ MT-LevelSafe


SEE ALSO
       door_bind(3C),    door_call(3C),    door_create(3C),     door_info(3C),
       door_revoke(3C),    door_server_create(3C),   door_setparam(3C),   fat‐
       tach(3C),      pthread_cleanup_pop(3C),       pthread_cleanup_push(3C),
       pthread_create(3C),  thr_create(3C), libdoor(3LIB), attributes(7), can‐
       cellation(7)



Oracle Solaris 11.4               13 Nov 2020                 door_xcreate(3C)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3