rpc_thread.c 3.4 KB

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