note.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* BUG BUG BUG */
  2. #include <u.h>
  3. #include <libc.h>
  4. #include <thread.h>
  5. #include "/sys/src/libthread/threadimpl.h"
  6. int _threadnopasser;
  7. #define NFN 33
  8. #define ERRLEN 48
  9. typedef struct Note Note;
  10. struct Note
  11. {
  12. Lock inuse;
  13. Proc *proc; /* recipient */
  14. char s[ERRMAX]; /* arg2 */
  15. };
  16. static Note notes[128];
  17. static Note *enotes = notes+nelem(notes);
  18. static int (*onnote[NFN])(void*, char*);
  19. static int onnotepid[NFN];
  20. static Lock onnotelock;
  21. int
  22. threadnotify(int (*f)(void*, char*), int in)
  23. {
  24. int i, topid;
  25. int (*from)(void*, char*), (*to)(void*, char*);
  26. if(in){
  27. from = nil;
  28. to = f;
  29. topid = _threadgetproc()->pid;
  30. }else{
  31. from = f;
  32. to = nil;
  33. topid = 0;
  34. }
  35. lock(&onnotelock);
  36. for(i=0; i<NFN; i++)
  37. if(onnote[i]==from){
  38. onnote[i] = to;
  39. onnotepid[i] = topid;
  40. break;
  41. }
  42. unlock(&onnotelock);
  43. return i<NFN;
  44. }
  45. static void
  46. delayednotes(Proc *p, void *v)
  47. {
  48. int i;
  49. Note *n;
  50. int (*fn)(void*, char*);
  51. if(!p->pending)
  52. return;
  53. p->pending = 0;
  54. for(n=notes; n<enotes; n++){
  55. if(n->proc == p){
  56. for(i=0; i<NFN; i++){
  57. if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
  58. continue;
  59. if((*fn)(v, n->s))
  60. break;
  61. }
  62. if(i==NFN){
  63. _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
  64. if(v != nil)
  65. noted(NDFLT);
  66. else if(strncmp(n->s, "sys:", 4)==0)
  67. abort();
  68. threadexitsall(n->s);
  69. }
  70. n->proc = nil;
  71. unlock(&n->inuse);
  72. }
  73. }
  74. }
  75. void
  76. _threadnote(void *v, char *s)
  77. {
  78. Proc *p;
  79. Note *n;
  80. _threaddebug(DBGNOTE, "Got note %s", s);
  81. // if(strncmp(s, "sys:", 4) == 0)
  82. // noted(NDFLT);
  83. // if(_threadexitsallstatus){
  84. // _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
  85. // _exits(_threadexitsallstatus);
  86. // }
  87. if(strcmp(s, "threadint")==0)
  88. noted(NCONT);
  89. p = _threadgetproc();
  90. if(p == nil)
  91. noted(NDFLT);
  92. for(n=notes; n<enotes; n++)
  93. if(canlock(&n->inuse))
  94. break;
  95. if(n==enotes)
  96. sysfatal("libthread: too many delayed notes");
  97. utfecpy(n->s, n->s+ERRMAX, s);
  98. n->proc = p;
  99. p->pending = 1;
  100. if(!p->splhi)
  101. delayednotes(p, v);
  102. noted(NCONT);
  103. }
  104. int
  105. _procsplhi(void)
  106. {
  107. int s;
  108. Proc *p;
  109. p = _threadgetproc();
  110. s = p->splhi;
  111. p->splhi = 1;
  112. return s;
  113. }
  114. void
  115. _procsplx(int s)
  116. {
  117. Proc *p;
  118. p = _threadgetproc();
  119. p->splhi = s;
  120. if(s)
  121. return;
  122. if(p->pending)
  123. delayednotes(p, nil);
  124. }