rpc_thread.c 3.9 KB

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