URI: 
       tlogf.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tlogf.c (3960B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <thread.h>
            5 #include <cursor.h>
            6 #include <mouse.h>
            7 #include <keyboard.h>
            8 #include <frame.h>
            9 #include <fcall.h>
           10 #include <plumb.h>
           11 #include <libsec.h>
           12 #include "dat.h"
           13 #include "fns.h"
           14 
           15 // State for global log file.
           16 typedef struct Log Log;
           17 struct Log
           18 {
           19         QLock lk;
           20         Rendez r;
           21 
           22         vlong start; // msg[0] corresponds to 'start' in the global sequence of events
           23 
           24         // queued events (nev=entries in ev, mev=capacity of p)
           25         char **ev;
           26         int nev;
           27         int mev;
           28 
           29         // open acme/put files that need to read events
           30         Fid **f;
           31         int nf;
           32         int mf;
           33 
           34         // active (blocked) reads waiting for events
           35         Xfid **read;
           36         int nread;
           37         int mread;
           38 };
           39 
           40 static Log eventlog;
           41 
           42 void
           43 xfidlogopen(Xfid *x)
           44 {
           45         qlock(&eventlog.lk);
           46         if(eventlog.nf >= eventlog.mf) {
           47                 eventlog.mf = eventlog.mf*2;
           48                 if(eventlog.mf == 0)
           49                         eventlog.mf = 8;
           50                 eventlog.f = erealloc(eventlog.f, eventlog.mf*sizeof eventlog.f[0]);
           51         }
           52         eventlog.f[eventlog.nf++] = x->f;
           53         x->f->logoff = eventlog.start + eventlog.nev;
           54 
           55         qunlock(&eventlog.lk);
           56 }
           57 
           58 void
           59 xfidlogclose(Xfid *x)
           60 {
           61         int i;
           62 
           63         qlock(&eventlog.lk);
           64         for(i=0; i<eventlog.nf; i++) {
           65                 if(eventlog.f[i] == x->f) {
           66                         eventlog.f[i] = eventlog.f[--eventlog.nf];
           67                         break;
           68                 }
           69         }
           70         qunlock(&eventlog.lk);
           71 }
           72 
           73 void
           74 xfidlogread(Xfid *x)
           75 {
           76         char *p;
           77         int i;
           78         Fcall fc;
           79 
           80         qlock(&eventlog.lk);
           81         if(eventlog.nread >= eventlog.mread) {
           82                 eventlog.mread = eventlog.mread*2;
           83                 if(eventlog.mread == 0)
           84                         eventlog.mread = 8;
           85                 eventlog.read = erealloc(eventlog.read, eventlog.mread*sizeof eventlog.read[0]);
           86         }
           87         eventlog.read[eventlog.nread++] = x;
           88 
           89         if(eventlog.r.l == nil)
           90                 eventlog.r.l = &eventlog.lk;
           91         x->flushed = FALSE;
           92         while(x->f->logoff >= eventlog.start+eventlog.nev && !x->flushed)
           93                 rsleep(&eventlog.r);
           94 
           95         for(i=0; i<eventlog.nread; i++) {
           96                 if(eventlog.read[i] == x) {
           97                         eventlog.read[i] = eventlog.read[--eventlog.nread];
           98                         break;
           99                 }
          100         }
          101 
          102         if(x->flushed) {
          103                 qunlock(&eventlog.lk);
          104                 return;
          105         }
          106 
          107         i = x->f->logoff - eventlog.start;
          108         p = estrdup(eventlog.ev[i]);
          109         x->f->logoff++;
          110         qunlock(&eventlog.lk);
          111 
          112         fc.data = p;
          113         fc.count = strlen(p);
          114         respond(x, &fc, nil);
          115         free(p);
          116 }
          117 
          118 void
          119 xfidlogflush(Xfid *x)
          120 {
          121         int i;
          122         Xfid *rx;
          123 
          124         qlock(&eventlog.lk);
          125         for(i=0; i<eventlog.nread; i++) {
          126                 rx = eventlog.read[i];
          127                 if(rx->fcall.tag == x->fcall.oldtag) {
          128                         rx->flushed = TRUE;
          129                         rwakeupall(&eventlog.r);
          130                 }
          131         }
          132         qunlock(&eventlog.lk);
          133 }
          134 
          135 /*
          136  * add a log entry for op on w.
          137  * expected calls:
          138  *
          139  * op == "new" for each new window
          140  *        - caller of coladd or makenewwindow responsible for calling
          141  *                xfidlog after setting window name
          142  *        - exception: zerox
          143  *
          144  * op == "zerox" for new window created via zerox
          145  *        - called from zeroxx
          146  *
          147  * op == "get" for Get executed on window
          148  *        - called from get
          149  *
          150  * op == "put" for Put executed on window
          151  *        - called from put
          152  *
          153  * op == "del" for deleted window
          154  *        - called from winclose
          155  */
          156 void
          157 xfidlog(Window *w, char *op)
          158 {
          159         int i, n;
          160         vlong min;
          161         File *f;
          162         char *name;
          163 
          164         qlock(&eventlog.lk);
          165         if(eventlog.nev >= eventlog.mev) {
          166                 // Remove and free any entries that all readers have read.
          167                 min = eventlog.start + eventlog.nev;
          168                 for(i=0; i<eventlog.nf; i++) {
          169                         if(min > eventlog.f[i]->logoff)
          170                                 min = eventlog.f[i]->logoff;
          171                 }
          172                 if(min > eventlog.start) {
          173                         n = min - eventlog.start;
          174                         for(i=0; i<n; i++)
          175                                 free(eventlog.ev[i]);
          176                         eventlog.nev -= n;
          177                         eventlog.start += n;
          178                         memmove(eventlog.ev, eventlog.ev+n, eventlog.nev*sizeof eventlog.ev[0]);
          179                 }
          180 
          181                 // Otherwise grow.
          182                 if(eventlog.nev >= eventlog.mev) {
          183                         eventlog.mev = eventlog.mev*2;
          184                         if(eventlog.mev == 0)
          185                                 eventlog.mev = 8;
          186                         eventlog.ev = erealloc(eventlog.ev, eventlog.mev*sizeof eventlog.ev[0]);
          187                 }
          188         }
          189         f = w->body.file;
          190         name = runetobyte(f->name, f->nname);
          191         if(name == nil)
          192                 name = estrdup("");
          193         eventlog.ev[eventlog.nev++] = smprint("%d %s %s\n", w->id, op, name);
          194         free(name);
          195         if(eventlog.r.l == nil)
          196                 eventlog.r.l = &eventlog.lk;
          197         rwakeupall(&eventlog.r);
          198         qunlock(&eventlog.lk);
          199 }