iocall.c 880 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include "threadimpl.h"
  5. long
  6. iocall(Ioproc *io, long (*op)(va_list*), ...)
  7. {
  8. int ret, inted;
  9. Ioproc *msg;
  10. if(send(io->c, &io) == -1){
  11. werrstr("interrupted");
  12. return -1;
  13. }
  14. assert(!io->inuse);
  15. io->inuse = 1;
  16. io->op = op;
  17. va_start(io->arg, op);
  18. msg = io;
  19. inted = 0;
  20. while(send(io->creply, &msg) == -1){
  21. msg = nil;
  22. inted = 1;
  23. }
  24. if(inted){
  25. werrstr("interrupted");
  26. return -1;
  27. }
  28. /*
  29. * If we get interrupted, we have to stick around so that
  30. * the IO proc has someone to talk to. Send it an interrupt
  31. * and try again.
  32. */
  33. inted = 0;
  34. while(recv(io->creply, nil) == -1){
  35. inted = 1;
  36. iointerrupt(io);
  37. }
  38. USED(inted);
  39. va_end(io->arg);
  40. ret = io->ret;
  41. if(ret < 0)
  42. errstr(io->err, sizeof io->err);
  43. io->inuse = 0;
  44. /* release resources */
  45. while(send(io->creply, &io) == -1)
  46. ;
  47. return ret;
  48. }