ioproc.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <thread.h>
  12. #include "threadimpl.h"
  13. enum
  14. {
  15. STACK = 8192,
  16. };
  17. void
  18. iointerrupt(Ioproc *io)
  19. {
  20. if(!io->inuse)
  21. return;
  22. threadint(io->tid);
  23. }
  24. static void
  25. xioproc(void *a)
  26. {
  27. Ioproc *io, *x;
  28. io = a;
  29. /*
  30. * first recvp acquires the ioproc.
  31. * second tells us that the data is ready.
  32. */
  33. for(;;){
  34. while(recv(io->c, &x) == -1)
  35. ;
  36. if(x == 0) /* our cue to leave */
  37. break;
  38. assert(x == io);
  39. /* caller is now committed -- even if interrupted he'll return */
  40. while(recv(io->creply, &x) == -1)
  41. ;
  42. if(x == 0) /* caller backed out */
  43. continue;
  44. assert(x == io);
  45. io->ret = io->op(&io->arg);
  46. if(io->ret < 0)
  47. rerrstr(io->err, sizeof io->err);
  48. while(send(io->creply, &io) == -1)
  49. ;
  50. while(recv(io->creply, &x) == -1)
  51. ;
  52. }
  53. }
  54. Ioproc*
  55. ioproc(void)
  56. {
  57. Ioproc *io;
  58. io = mallocz(sizeof(*io), 1);
  59. if(io == nil)
  60. sysfatal("ioproc malloc: %r");
  61. io->c = chancreate(sizeof(void*), 0);
  62. io->creply = chancreate(sizeof(void*), 0);
  63. io->tid = proccreate(xioproc, io, STACK);
  64. return io;
  65. }
  66. void
  67. closeioproc(Ioproc *io)
  68. {
  69. if(io == nil)
  70. return;
  71. iointerrupt(io);
  72. while(send(io->c, 0) == -1)
  73. ;
  74. chanfree(io->c);
  75. chanfree(io->creply);
  76. free(io);
  77. }