ioproc.c 928 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include "threadimpl.h"
  5. enum
  6. {
  7. STACK = 8192,
  8. };
  9. static Ioproc *iofree;
  10. void
  11. iointerrupt(Ioproc *io)
  12. {
  13. if(!io->inuse)
  14. return;
  15. postnote(PNPROC, io->pid, "interrupt");
  16. }
  17. static void
  18. xioproc(void *a)
  19. {
  20. Ioproc *io;
  21. io = a;
  22. io->pid = getpid();
  23. sendp(io->c, nil);
  24. while(recvp(io->c) == io){
  25. io->ret = io->op(&io->arg);
  26. if(io->ret < 0)
  27. rerrstr(io->err, sizeof io->err);
  28. sendp(io->c, io);
  29. }
  30. chanfree(io->c);
  31. free(io);
  32. }
  33. Ioproc*
  34. ioproc(void)
  35. {
  36. Ioproc *io;
  37. if((io = iofree) != nil){
  38. iofree = io->next;
  39. return io;
  40. }
  41. io = mallocz(sizeof(*io), 1);
  42. if(io == nil)
  43. sysfatal("ioproc malloc: %r");
  44. io->c = chancreate(sizeof(void*), 0);
  45. if(proccreate(xioproc, io, STACK) < 0)
  46. sysfatal("ioproc proccreate: %r");
  47. recvp(io->c);
  48. return io;
  49. }
  50. void
  51. closeioproc(Ioproc *io)
  52. {
  53. if(io == nil)
  54. return;
  55. iointerrupt(io);
  56. io->next = iofree;
  57. iofree = io;
  58. }