rpc_thread.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. #define __FORCE_GLIBC
  7. #include <features.h>
  8. #include <stdio.h>
  9. #include <assert.h>
  10. #include "rpc_private.h"
  11. libc_hidden_proto(__rpc_thread_svc_fdset)
  12. libc_hidden_proto(__rpc_thread_createerr)
  13. libc_hidden_proto(__rpc_thread_svc_pollfd)
  14. libc_hidden_proto(__rpc_thread_svc_max_pollfd)
  15. #ifdef __UCLIBC_HAS_THREADS__
  16. #include <bits/libc-tsd.h>
  17. /* Variable used in non-threaded applications or for the first thread. */
  18. static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
  19. __libc_tsd_define (, RPC_VARS)
  20. /*
  21. * Task-variable destructor
  22. */
  23. void
  24. __rpc_thread_destroy (void)
  25. {
  26. struct rpc_thread_variables *tvp = __libc_tsd_get (RPC_VARS);
  27. if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) {
  28. __rpc_thread_svc_cleanup ();
  29. __rpc_thread_clnt_cleanup ();
  30. /*__rpc_thread_key_cleanup (); */
  31. free (tvp->authnone_private_s);
  32. free (tvp->clnt_perr_buf_s);
  33. free (tvp->clntraw_private_s);
  34. free (tvp->svcraw_private_s);
  35. free (tvp->authdes_cache_s);
  36. free (tvp->authdes_lru_s);
  37. free (tvp);
  38. __libc_tsd_set (RPC_VARS, NULL);
  39. }
  40. }
  41. /*
  42. * Initialize RPC multi-threaded operation
  43. */
  44. static void
  45. rpc_thread_multi (void)
  46. {
  47. __libc_tsd_set (RPC_VARS, &__libc_tsd_RPC_VARS_mem);
  48. }
  49. struct rpc_thread_variables attribute_hidden *
  50. __rpc_thread_variables (void)
  51. {
  52. __libc_once_define (static, once);
  53. struct rpc_thread_variables *tvp;
  54. tvp = __libc_tsd_get (RPC_VARS);
  55. if (tvp == NULL) {
  56. __libc_once (once, rpc_thread_multi);
  57. tvp = __libc_tsd_get (RPC_VARS);
  58. if (tvp == NULL) {
  59. tvp = calloc (1, sizeof *tvp);
  60. if (tvp != NULL)
  61. __libc_tsd_set (RPC_VARS, tvp);
  62. else
  63. tvp = __libc_tsd_get (RPC_VARS);
  64. }
  65. }
  66. return tvp;
  67. }
  68. /* Global variables If we're single-threaded, or if this is the first
  69. thread using the variable, use the existing global variable. This
  70. provides backwards compatability for existing applications which
  71. dynamically link against this code. */
  72. #undef svc_fdset
  73. #undef rpc_createerr
  74. #undef svc_pollfd
  75. #undef svc_max_pollfd
  76. fd_set *
  77. __rpc_thread_svc_fdset (void)
  78. {
  79. struct rpc_thread_variables *tvp;
  80. tvp = __rpc_thread_variables ();
  81. if (tvp == &__libc_tsd_RPC_VARS_mem)
  82. return &svc_fdset;
  83. return &tvp->svc_fdset_s;
  84. }
  85. struct rpc_createerr *
  86. __rpc_thread_createerr (void)
  87. {
  88. struct rpc_thread_variables *tvp;
  89. tvp = __rpc_thread_variables ();
  90. if (tvp == &__libc_tsd_RPC_VARS_mem)
  91. return &rpc_createerr;
  92. return &tvp->rpc_createerr_s;
  93. }
  94. struct pollfd **
  95. __rpc_thread_svc_pollfd (void)
  96. {
  97. struct rpc_thread_variables *tvp;
  98. tvp = __rpc_thread_variables ();
  99. if (tvp == &__libc_tsd_RPC_VARS_mem)
  100. return &svc_pollfd;
  101. return &tvp->svc_pollfd_s;
  102. }
  103. int *
  104. __rpc_thread_svc_max_pollfd (void)
  105. {
  106. struct rpc_thread_variables *tvp;
  107. tvp = __rpc_thread_variables ();
  108. if (tvp == &__libc_tsd_RPC_VARS_mem)
  109. return &svc_max_pollfd;
  110. return &tvp->svc_max_pollfd_s;
  111. }
  112. #else
  113. #undef svc_fdset
  114. #undef rpc_createerr
  115. #undef svc_pollfd
  116. #undef svc_max_pollfd
  117. extern fd_set svc_fdset;
  118. fd_set * __rpc_thread_svc_fdset (void)
  119. {
  120. return &(svc_fdset);
  121. }
  122. extern struct rpc_createerr rpc_createerr;
  123. struct rpc_createerr * __rpc_thread_createerr (void)
  124. {
  125. return &(rpc_createerr);
  126. }
  127. extern struct pollfd *svc_pollfd;
  128. struct pollfd ** __rpc_thread_svc_pollfd (void)
  129. {
  130. return &(svc_pollfd);
  131. }
  132. extern int svc_max_pollfd;
  133. int * __rpc_thread_svc_max_pollfd (void)
  134. {
  135. return &(svc_max_pollfd);
  136. }
  137. #endif /* __UCLIBC_HAS_THREADS__ */
  138. libc_hidden_def(__rpc_thread_svc_fdset)
  139. libc_hidden_def(__rpc_thread_createerr)
  140. libc_hidden_def(__rpc_thread_svc_pollfd)
  141. libc_hidden_def(__rpc_thread_svc_max_pollfd)