rpc_thread.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #define __FORCE_GLIBC
  2. #include <features.h>
  3. #include <stdio.h>
  4. #include <assert.h>
  5. #include "rpc_private.h"
  6. #ifdef __UCLIBC_HAS_THREADS__
  7. #include <bits/libc-tsd.h>
  8. /* Variable used in non-threaded applications or for the first thread. */
  9. static struct rpc_thread_variables __libc_tsd_RPC_VARS_mem;
  10. static struct rpc_thread_variables *__libc_tsd_RPC_VARS_data =
  11. &__libc_tsd_RPC_VARS_mem;
  12. /*
  13. * Task-variable destructor
  14. */
  15. void
  16. __rpc_thread_destroy (void)
  17. {
  18. struct rpc_thread_variables *tvp = __rpc_thread_variables();
  19. if (tvp != NULL && tvp != &__libc_tsd_RPC_VARS_mem) {
  20. __rpc_thread_svc_cleanup ();
  21. __rpc_thread_clnt_cleanup ();
  22. //__rpc_thread_key_cleanup ();
  23. free (tvp->authnone_private_s);
  24. free (tvp->clnt_perr_buf_s);
  25. free (tvp->clntraw_private_s);
  26. free (tvp->svcraw_private_s);
  27. free (tvp->authdes_cache_s);
  28. free (tvp->authdes_lru_s);
  29. free (tvp);
  30. }
  31. }
  32. /* XXX: maybe turn this into a normal __pthread_once() via pthreads/weaks.c ? */
  33. extern int weak_function __pthread_once (pthread_once_t *__once_control,
  34. void (*__init_routine) (void));
  35. # define __libc_once_define(CLASS, NAME) \
  36. CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT
  37. /* Call handler iff the first call. */
  38. #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
  39. do { \
  40. if (__pthread_once != NULL) \
  41. __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \
  42. else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \
  43. INIT_FUNCTION (); \
  44. (ONCE_CONTROL) = !PTHREAD_ONCE_INIT; \
  45. } \
  46. } while (0)
  47. /*
  48. * Initialize RPC multi-threaded operation
  49. */
  50. static void
  51. rpc_thread_multi (void)
  52. {
  53. __libc_tsd_set (RPC_VARS, &__libc_tsd_RPC_VARS_mem);
  54. }
  55. struct rpc_thread_variables attribute_hidden *
  56. __rpc_thread_variables (void)
  57. {
  58. __libc_once_define (static, once);
  59. struct rpc_thread_variables *tvp;
  60. tvp = __libc_tsd_get (RPC_VARS);
  61. if (tvp == NULL) {
  62. __libc_once (once, rpc_thread_multi);
  63. tvp = __libc_tsd_get (RPC_VARS);
  64. if (tvp == NULL) {
  65. tvp = calloc (1, sizeof *tvp);
  66. if (tvp != NULL)
  67. __libc_tsd_set (RPC_VARS, tvp);
  68. else
  69. tvp = __libc_tsd_RPC_VARS_data;
  70. }
  71. }
  72. return tvp;
  73. }
  74. /* Global variables If we're single-threaded, or if this is the first
  75. thread using the variable, use the existing global variable. This
  76. provides backwards compatability for existing applications which
  77. dynamically link against this code. */
  78. #undef svc_fdset
  79. #undef rpc_createerr
  80. #undef svc_pollfd
  81. #undef svc_max_pollfd
  82. fd_set attribute_hidden *
  83. __rpc_thread_svc_fdset_internal (void)
  84. {
  85. struct rpc_thread_variables *tvp;
  86. tvp = __rpc_thread_variables ();
  87. if (tvp == &__libc_tsd_RPC_VARS_mem)
  88. return &svc_fdset;
  89. return &tvp->svc_fdset_s;
  90. }
  91. strong_alias(__rpc_thread_svc_fdset_internal,__rpc_thread_svc_fdset)
  92. struct rpc_createerr *
  93. __rpc_thread_createerr (void)
  94. {
  95. struct rpc_thread_variables *tvp;
  96. tvp = __rpc_thread_variables ();
  97. if (tvp == &__libc_tsd_RPC_VARS_mem)
  98. return &rpc_createerr;
  99. return &tvp->rpc_createerr_s;
  100. }
  101. struct pollfd attribute_hidden **
  102. __rpc_thread_svc_pollfd_internal (void)
  103. {
  104. struct rpc_thread_variables *tvp;
  105. tvp = __rpc_thread_variables ();
  106. if (tvp == &__libc_tsd_RPC_VARS_mem)
  107. return &svc_pollfd;
  108. return &tvp->svc_pollfd_s;
  109. }
  110. strong_alias(__rpc_thread_svc_pollfd_internal,__rpc_thread_svc_pollfd)
  111. int attribute_hidden *
  112. __rpc_thread_svc_max_pollfd_internal (void)
  113. {
  114. struct rpc_thread_variables *tvp;
  115. tvp = __rpc_thread_variables ();
  116. if (tvp == &__libc_tsd_RPC_VARS_mem)
  117. return &svc_max_pollfd;
  118. return &tvp->svc_max_pollfd_s;
  119. }
  120. strong_alias(__rpc_thread_svc_max_pollfd_internal,__rpc_thread_svc_max_pollfd)
  121. #else
  122. #undef svc_fdset
  123. #undef rpc_createerr
  124. #undef svc_pollfd
  125. #undef svc_max_pollfd
  126. fd_set attribute_hidden * __rpc_thread_svc_fdset_internal (void)
  127. {
  128. extern fd_set svc_fdset;
  129. return &(svc_fdset);
  130. }
  131. strong_alias(__rpc_thread_svc_fdset_internal,__rpc_thread_svc_fdset)
  132. struct rpc_createerr * __rpc_thread_createerr (void)
  133. {
  134. extern struct rpc_createerr rpc_createerr;
  135. return &(rpc_createerr);
  136. }
  137. struct pollfd attribute_hidden ** __rpc_thread_svc_pollfd_internal (void)
  138. {
  139. extern struct pollfd *svc_pollfd;
  140. return &(svc_pollfd);
  141. }
  142. strong_alias(__rpc_thread_svc_pollfd_internal,__rpc_thread_svc_pollfd)
  143. int attribute_hidden * __rpc_thread_svc_max_pollfd_internal (void)
  144. {
  145. extern int svc_max_pollfd;
  146. return &(svc_max_pollfd);
  147. }
  148. strong_alias(__rpc_thread_svc_max_pollfd_internal,__rpc_thread_svc_max_pollfd)
  149. #endif /* __UCLIBC_HAS_THREADS__ */