boilerplate.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <thread.h>
  4. #include <fcall.h>
  5. #include "playlist.h"
  6. static Channel *reqs;
  7. Req*
  8. reqalloc(void)
  9. {
  10. Req *r;
  11. if(reqs == nil)
  12. reqs = chancreate(sizeof(Req*), 256);
  13. if(r = nbrecvp(reqs))
  14. return r;
  15. r = malloc(sizeof(Req));
  16. return r;
  17. }
  18. void
  19. reqfree(Req *r)
  20. {
  21. if(!nbsendp(reqs, r))
  22. free(r);
  23. }
  24. Wmsg
  25. waitmsg(Worker *w, Channel *q)
  26. {
  27. Wmsg m;
  28. sendp(q, w);
  29. recv(w->eventc, &m);
  30. return m;
  31. }
  32. int
  33. sendmsg(Channel *q, Wmsg *m)
  34. {
  35. Worker *w;
  36. while(w = nbrecvp(q)){
  37. /* Test for markerdom (see bcastmsg) */
  38. if(w->eventc){
  39. send(w->eventc, m);
  40. return 1;
  41. }
  42. sendp(q, w); /* put back */
  43. }
  44. return 0;
  45. }
  46. void
  47. bcastmsg(Channel *q, Wmsg *m)
  48. {
  49. Worker *w, marker;
  50. void *a;
  51. a = m->arg;
  52. /*
  53. * Use a marker to mark the end of the queue.
  54. * This prevents workers from getting the
  55. * broadcast and putting themselves back on the
  56. * queue before the broadcast has finished
  57. */
  58. marker.eventc = nil; /* Only markers have eventc == nil */
  59. sendp(q, &marker);
  60. while((w = recvp(q)) != &marker){
  61. if(w->eventc == nil){
  62. /* somebody else's marker, put it back */
  63. sendp(q, w);
  64. }else{
  65. if(a) m->arg = strdup(a);
  66. send(w->eventc, m);
  67. }
  68. }
  69. free(a);
  70. m->arg = nil;
  71. }
  72. void
  73. readbuf(Req *r, void *s, long n)
  74. {
  75. r->ofcall.count = r->ifcall.count;
  76. if(r->ifcall.offset >= n){
  77. r->ofcall.count = 0;
  78. return;
  79. }
  80. if(r->ifcall.offset+r->ofcall.count > n)
  81. r->ofcall.count = n - r->ifcall.offset;
  82. memmove(r->ofcall.data, (char*)s+r->ifcall.offset, r->ofcall.count);
  83. }
  84. void
  85. readstr(Req *r, char *s)
  86. {
  87. readbuf(r, s, strlen(s));
  88. }