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

개요

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

door_xcreate(3c)

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 *cookie, char *argp,
             size_t arg_size, door_desc_t *dp, uint_t n_desc);


       typedef int door_xcreate_server_func_t(door_info_t *dip,
            void *(*thr_start_func)(void *arg), void *crarg, void *cookie);


       typedef void door_xcreate_thrsetup_func_t(void *crcookie);


       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 as‐
                  sociated 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(3C).


   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 at‐
                  tribute  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 im‐
                      plementation-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  se‐
       curity  should not place secure information in door data that is acces‐
       sible 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_re‐
       voke(3C).  This  closes  the  associated file descriptor, and acts as a
       barrier to further door invocations, but  existing  active  invocations
       are  not  guaranteed  to  have  completed before door_revoke() returns.
       Server threads bound to a revoked door do not wakeup or exit  automati‐
       cally 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  re‐
                  quired amount will exceed the stack bounds then E2BIG is re‐
                  turned.


       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 a pool of 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



       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_re‐
       voke(3C),   door_server_create(3C),   door_setparam(3C),   fattach(3C),
       pthread_cleanup_pop(3C),  pthread_cleanup_push(3C), pthread_create(3C),
       thr_create(3C), libdoor(3LIB), attributes(7), cancellation(7)

HISTORY
       The door_xcreate() function was introduced in Solaris 10  9/10  (Update
       9).

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