23f3361997-02-27Fredrik Hübinette (Hubbe) constant Mutex=__builtin.mutex; constant Condition=__builtin.condition;
609c0f1997-02-27Fredrik Hübinette (Hubbe)  class Fifo {
7f30a61997-02-27Fredrik Hübinette (Hubbe)  inherit Condition : r_cond;
d4bf591999-06-12Henrik Grubbström (Grubba)  inherit Condition : w_cond; inherit Mutex : lock;
609c0f1997-02-27Fredrik Hübinette (Hubbe) 
37d0891998-05-27Fredrik Hübinette (Hubbe)  array buffer;
87e3691997-02-27Fredrik Hübinette (Hubbe)  int ptr, num;
37d0891998-05-27Fredrik Hübinette (Hubbe)  int read_tres, write_tres;
609c0f1997-02-27Fredrik Hübinette (Hubbe) 
87e3691997-02-27Fredrik Hübinette (Hubbe)  int size() { return num; }
609c0f1997-02-27Fredrik Hübinette (Hubbe)  mixed read()
d4bf591999-06-12Henrik Grubbström (Grubba)  { mixed tmp; object key=lock::lock(); while(!num) r_cond::wait(key); tmp=buffer[ptr]; buffer[ptr++] = 0; // Throw away any references. ptr%=sizeof(buffer); if(read_tres < sizeof(buffer))
609c0f1997-02-27Fredrik Hübinette (Hubbe)  {
d4bf591999-06-12Henrik Grubbström (Grubba)  if(num-- == read_tres) w_cond::broadcast(); }else{ num--; w_cond::signal();
609c0f1997-02-27Fredrik Hübinette (Hubbe)  }
d4bf591999-06-12Henrik Grubbström (Grubba)  return tmp; }
37d0891998-05-27Fredrik Hübinette (Hubbe)  array read_array() { array ret; object key=lock::lock(); while(!num) r_cond::wait(key); if(num==1) { ret=buffer[ptr..ptr]; buffer[ptr++] = 0; // Throw away any references. ptr%=sizeof(buffer); num--; }else{ ret=buffer[ptr..]+buffer[..num-sizeof(ret)-1]; ptr=num=0; buffer=allocate(sizeof(buffer)); // Throw away any references. }
dc731d1999-06-19Fredrik Hübinette (Hubbe)  w_cond::broadcast();
37d0891998-05-27Fredrik Hübinette (Hubbe)  return ret; }
609c0f1997-02-27Fredrik Hübinette (Hubbe)  void write(mixed v)
d4bf591999-06-12Henrik Grubbström (Grubba)  { object key=lock::lock(); while(num == sizeof(buffer)) w_cond::wait(key); buffer[(ptr + num) % sizeof(buffer)]=v; if(write_tres)
609c0f1997-02-27Fredrik Hübinette (Hubbe)  {
d4bf591999-06-12Henrik Grubbström (Grubba)  if(num++ == write_tres) r_cond::broadcast(); }else{ num++; r_cond::signal();
609c0f1997-02-27Fredrik Hübinette (Hubbe)  }
d4bf591999-06-12Henrik Grubbström (Grubba)  }
37d0891998-05-27Fredrik Hübinette (Hubbe) 
8d49101998-01-21Fredrik Hübinette (Hubbe)  void create(int|void size)
d4bf591999-06-12Henrik Grubbström (Grubba)  { write_tres=0; buffer=allocate(read_tres=size || 128); }
609c0f1997-02-27Fredrik Hübinette (Hubbe) }; class Queue {
d4bf591999-06-12Henrik Grubbström (Grubba)  inherit Condition : r_cond; inherit Mutex : lock;
609c0f1997-02-27Fredrik Hübinette (Hubbe)  mixed *buffer=allocate(16); int r_ptr, w_ptr; int size() { return w_ptr - r_ptr; } mixed read()
d4bf591999-06-12Henrik Grubbström (Grubba)  { mixed tmp; object key=lock::lock(); while(!size()) r_cond::wait(key); tmp=buffer[r_ptr]; buffer[r_ptr++] = 0; // Throw away any references. key=0; return tmp; }
609c0f1997-02-27Fredrik Hübinette (Hubbe)  void write(mixed v)
d4bf591999-06-12Henrik Grubbström (Grubba)  { object key=lock::lock(); if(w_ptr >= sizeof(buffer))
609c0f1997-02-27Fredrik Hübinette (Hubbe)  {
d4bf591999-06-12Henrik Grubbström (Grubba)  buffer=buffer[r_ptr..]; buffer+=allocate(sizeof(buffer)+1); w_ptr-=r_ptr; r_ptr=0;
609c0f1997-02-27Fredrik Hübinette (Hubbe)  }
d4bf591999-06-12Henrik Grubbström (Grubba)  buffer[w_ptr]=v; w_ptr++; key=0; // Must free this one _before_ the signal... r_cond::signal(); }
609c0f1997-02-27Fredrik Hübinette (Hubbe) };