cancel.h 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. #ifndef _CANCEL_H
  7. #define _CANCEL_H
  8. /*
  9. * Usage of this header:
  10. * 1. define a static or hidden function __NC(NAME) - expands to __NAME_nocancel
  11. * 2. if it is hidden, add the prototype to the appropiate header where NAME has
  12. * it's prototype (guarded by _LIBC)
  13. * 3. add a CANCELLABLE_SYSCALL(...) line at the end, this will create the function
  14. * NAME (as weak) with enabled cancellation for NPTL, for
  15. * LT it will also create a strong_alias to __libc_NAME to be used in libpthread
  16. * 4. if you need libc_hidden_(weak|def) line, use instead lt_libc_hidden, this will
  17. * take care of the correct type, weak or strong depending on the THREADS type
  18. * 5. If the implementation can't be done using CANCELLABLE_SYSCALL (like for fcntl)
  19. * you need to manually add lt_strong_alias() line too, to optionally create the
  20. * __libc_NAME alias
  21. * 6. if functions are needed to implement __NC(NAME), that themselves are cancellable,
  22. * decide how the cancellation should be solved, two variants are possible:
  23. * a. use the other function as __NC(FUNC), this way you access the non-cancellable
  24. * variant and provide by CANCELLABLE_SYSCALL(...) the dedicated cancellation for NAME.
  25. * be aware, that for this case __NC(FUNC) has to be hidden (not static)
  26. * b. use the other function with it's name (FUNC) and add LIBC_CANCEL_HANDLED(); at
  27. * the end of file with a comment telling us which function took care of the cancellation
  28. * Note: LIBC_CANCEL_HANDLED() is noop on uClibc, glibc uses it only for tests, we use
  29. * it only for "documentation".
  30. *
  31. * For now the use of this file is limited to libc, will expand later to support libpthread
  32. * and librt as well.
  33. */
  34. #include <features.h>
  35. #define __NC(name) _NC(name)
  36. #define _NC(name) __##name##_nocancel
  37. #define __NC_OLD(name) _NC_OLD(name)
  38. #define _NC_OLD(name) __libc_##name
  39. #define __NC_PROTO(name) extern __typeof(name) __NC(name) attribute_hidden;
  40. #define __NC_OLD_PROTO(name) extern __typeof(name) __NC_OLD(name);
  41. #if defined __UCLIBC_HAS_THREADS__ && !defined __UCLIBC_HAS_LINUXTHREADS__
  42. # define __NEW_THREADS 1
  43. #else
  44. # define SINGLE_THREAD_P 1
  45. #endif
  46. #ifdef __NEW_THREADS
  47. # include <sysdep-cancel.h>
  48. # define CANCELLABLE_SYSCALL(res_type, name, param_list, params) \
  49. res_type weak_function name param_list \
  50. { \
  51. int oldtype; \
  52. res_type result; \
  53. if (SINGLE_THREAD_P) \
  54. return __NC(name) params; \
  55. oldtype = LIBC_CANCEL_ASYNC(); \
  56. result = __NC(name) params; \
  57. LIBC_CANCEL_RESET(oldtype); \
  58. return result; \
  59. }
  60. # define lt_strong_alias(name)
  61. # define lt_libc_hidden(name) libc_hidden_def(name)
  62. #elif defined __UCLIBC_HAS_LINUXTHREADS__
  63. # define CANCELLABLE_SYSCALL(res_type, name, param_list, params) \
  64. weak_alias(__NC(name),name) \
  65. lt_strong_alias(name)
  66. # define lt_strong_alias(name) \
  67. __NC_OLD_PROTO(name) \
  68. strong_alias(name,__NC_OLD(name))
  69. # define lt_libc_hidden(name) libc_hidden_weak(name)
  70. #else
  71. # define CANCELLABLE_SYSCALL(res_type, name, param_list, params) \
  72. strong_alias(__NC(name),name)
  73. # define lt_strong_alias(name)
  74. # define lt_libc_hidden(name) libc_hidden_def(name)
  75. #endif
  76. /* disable it, useless, glibc uses it only for tests */
  77. # undef LIBC_CANCEL_HANDLED
  78. # define LIBC_CANCEL_HANDLED()
  79. #endif