primblok.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /*
  6. * File: primblok.c
  7. * Purpose: testing whether the primordial thread can block in a
  8. * native blocking function without affecting the correct
  9. * functioning of NSPR I/O functions (Bugzilla bug #30746)
  10. */
  11. #if !defined(WINNT)
  12. #include <stdio.h>
  13. int main(int argc, char **argv)
  14. {
  15. printf("This test is not relevant on this platform\n");
  16. return 0;
  17. }
  18. #else /* WINNT */
  19. #include "nspr.h"
  20. #include <windows.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #define TEST_FILE_NAME "primblok.dat"
  25. /* use InterlockedExchange to update this variable */
  26. static LONG iothread_done;
  27. static void PR_CALLBACK IOThread(void *arg)
  28. {
  29. PRFileDesc *fd;
  30. char buf[32];
  31. PRInt32 nbytes;
  32. /* Give the primordial thread one second to block */
  33. Sleep(1000);
  34. /*
  35. * See if our PR_Write call will hang when the primordial
  36. * thread is blocking in a native blocking function.
  37. */
  38. fd = PR_Open(TEST_FILE_NAME, PR_WRONLY|PR_CREATE_FILE, 0666);
  39. if (NULL == fd) {
  40. fprintf(stderr, "PR_Open failed\n");
  41. exit(1);
  42. }
  43. memset(buf, 0xaf, sizeof(buf));
  44. fprintf(stderr, "iothread: calling PR_Write\n");
  45. nbytes = PR_Write(fd, buf, sizeof(buf));
  46. fprintf(stderr, "iothread: PR_Write returned\n");
  47. if (nbytes != sizeof(buf)) {
  48. fprintf(stderr, "PR_Write returned %d\n", nbytes);
  49. exit(1);
  50. }
  51. if (PR_Close(fd) == PR_FAILURE) {
  52. fprintf(stderr, "PR_Close failed\n");
  53. exit(1);
  54. }
  55. if (PR_Delete(TEST_FILE_NAME) == PR_FAILURE) {
  56. fprintf(stderr, "PR_Delete failed\n");
  57. exit(1);
  58. }
  59. /* Tell the main thread that we are done */
  60. InterlockedExchange(&iothread_done, 1);
  61. }
  62. int main(int argc, char **argv)
  63. {
  64. PRThread *iothread;
  65. /* Must be a global thread */
  66. iothread = PR_CreateThread(
  67. PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL,
  68. PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
  69. if (iothread == NULL) {
  70. fprintf(stderr, "cannot create thread\n");
  71. exit(1);
  72. }
  73. /*
  74. * Block in a native blocking function.
  75. * Give iothread 5 seconds to finish its task.
  76. */
  77. Sleep(5000);
  78. /*
  79. * Is iothread done or is it hung?
  80. *
  81. * I'm actually only interested in reading the value
  82. * of iothread_done. I'm using InterlockedExchange as
  83. * a thread-safe way to read iothread_done.
  84. */
  85. if (InterlockedExchange(&iothread_done, 1) == 0) {
  86. fprintf(stderr, "iothread is hung\n");
  87. fprintf(stderr, "FAILED\n");
  88. exit(1);
  89. }
  90. if (PR_JoinThread(iothread) == PR_FAILURE) {
  91. fprintf(stderr, "PR_JoinThread failed\n");
  92. exit(1);
  93. }
  94. printf("PASSED\n");
  95. return 0;
  96. } /* main */
  97. #endif /* WINNT */