コード例 #1
0
ファイル: db_view.c プロジェクト: pahihu/mumps
void DB_ViewPut(int vol, struct GBD *ptr)		// que block for write
{ short s;						// for funcs

  volnum = vol;						// for ron
  writing = 0;						// clear this
  s = SemOp(SEM_GLOBAL, WRITE);				// write lock
  if (s < 0)						// check error
  { return;						// quit if so
  }
  ptr->last_accessed = MTIME(0);			// reset access
  if (ptr->mem->type)					// if used
  { Used_block(ptr->block);				// mark it so
  }
  else 							// trying to free it
  { Free_block(ptr->block);				// do so
    bzero(ptr->mem, systab->vol[(volnum)-1]->vollab->block_size); // clear it
  }
  level = 0;						// for Queit
  if (ptr->dirty == NULL)				// check dirty ptr
  { ptr->dirty = ptr;					// set if reqd
    blk[level] = ptr;					// ditto
    Queit();						// do this
  }
  if (curr_lock)
  { SemOp(SEM_GLOBAL, -curr_lock);			// release lock
  }
  return;						// and exit
}
コード例 #2
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_GetLen( mvar *var, int lock, u_char *buf)	// length of node
{ short s;						// for returns
  int sav;						// save curr_lock

  if ((lock == -1) && (buf == NULL))			// just unlock?
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// unlock it
    }
    return 0;						// exit
  }
  sav = curr_lock;					// save this
  s = Copy2local(var);					// get local copy
  curr_lock = sav;					// restore current lock
  if (s < 0)						// check for error
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return s;						// and return
  }
  s = Get_data(0);					// attempt to get it

  if (s < 0)						// check for error
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return s;						// and return
  }
  if (buf != NULL)					// want data?
  { s = mcopy(record->buf, buf, record->len);		// copy the data
  }
  if ((lock != 1) && (curr_lock))			// preserve lock?
  { SemOp( SEM_GLOBAL, -curr_lock);			// no - release it
  }
  return s;						// and exit
}
コード例 #3
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Data(mvar *var, u_char *buf)	          	// get $DATA()
{ short s;						// for returns
  int i;						// a handy int

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  systab->vol[volnum-1]->stats.dbdat++;                 // update stats
  s = Get_data(0);					// attempt to get it
  i = 1;						// assume data found
  if (s == -ERRM7)					// undefined global?
  { i = 0;						// yes - no data
    if (level == 0)					// check for global
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      buf[0] = '0';					// zero to return
      buf[1] = '\0';					// null terminated
      return 1;						// and exit
    }
  }
  else if (s < 0)					// if it failed
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return s;						// and exit
  }
  if ((!db_var.slen) && (!i))				// pointing at 1st
  { Index++;
  }
  if ((i) || (Index > blk[level]->mem->last_idx))	// found or passed end
  { s = Locate_next();					// get next record
    if (s == -ERRM7)					// any more?
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return itocstring(buf, i);			// return result
    }
    else if (s < 0)					// error?
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return s;						// and exit
    }
  }							// got next record
  if (((db_var.slen < keybuf[0]) &&			// if smaller key and
       (bcmp(&keybuf[1], db_var.key, db_var.slen) == 0)) || // a descendant?
       (!db_var.slen))
  { i += 10;						// add 10 to result
  }
  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  return itocstring(buf, i);				// return result
}
コード例 #4
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_QueryD(mvar *var, u_char *buf) 		// get next key
{ short s;						// for returns
//  int i;						// a handy int

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  s = Get_data(0);					// try to find that
  if ((s < 0) && (s != -ERRM7))				// check for errors
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return s;						// and return the error
  }
  if ((level == 0) && (s == -ERRM7))			// if no such global
  { buf[0] = '\0';					// null terminate ret
    if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return -(ERRMLAST+ERRZ55);				// and return
  }

  if ((s < 0) && (db_var.slen))				// If we had a "real"
  { Index--;						// <UNDEF> last time
  }							// back up Index

  s = Locate_next();					// point at next
  if (s < 0)						// not found or error
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    if (s == -ERRM7)					// if no more
    { s = -(ERRMLAST+ERRZ55);				// say 'at end'
    }
    return s;						// done
  }

//  for (i = 10; i <= Index; i++)			// scan to current
//  { chunk = (cstring *) &iidx[idx[i]];             	// point at the chunk
//    bcopy(&chunk->buf[2], &keybuf[chunk->buf[0]+1],
//	  chunk->buf[1]);				// update the key
//    keybuf[0] = chunk->buf[0] + chunk->buf[1];	// and the size
//  }
  bcopy(&keybuf[1], var->key, (int) keybuf[0]);		// copy in the key
  var->slen = keybuf[0];				// update the length
  s = mcopy(record->buf, buf, record->len);		// copy the data
  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  return s;						// return the count
}
コード例 #5
0
ファイル: db_view.c プロジェクト: pahihu/mumps
void DB_ViewRel(int vol, struct GBD *ptr)	      	// release block, gbd
{ short s;						// for functions

  writing = 0;						// clear this
  ptr->last_accessed = MTIME(0);			// reset access
  if (ptr->dirty != NULL)				// not owned elsewhere
  { s = SemOp(SEM_GLOBAL, WRITE);			// write lock
    if (s < 0)						// check error
    { return;						// quit if so
// PROBABLY SHOULD PERSIST HERE
    }
    Free_GBD(ptr);					// free it
    SemOp(SEM_GLOBAL, -curr_lock);			// release lock
  }
  return;						// and exit
}
コード例 #6
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
int DB_Free(int vol)	                           	// total free blocks
{ short s;						// for funcs
  u_int i;						// loop cnt
  int count = 0;					// blk count

  s = SemOp( SEM_GLOBAL, READ);				// lock the globals
  if (s < 0)
  { return s;						// return any errors
  }
  for (i = 1;						// start at block 1
	i <= systab->vol[vol-1]->vollab->max_block;  	// while still in map
        i++)						// going up by one
  { count +=		 				// add up blocks
	(((((u_char *)systab->vol[vol-1]->map)[i>>3]) &(1<<(i&7))) == 0);
  }
  SemOp( SEM_GLOBAL, -curr_lock);			// unlock the globals
  return count;						// return the count
}							// end DB_Free
コード例 #7
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
int DB_SetFlags(mvar *var, int flags)                  	// Set flags
{ int clearit = 0;
  int i;
  short s;

  if (flags < 0)
  { clearit = 1;					// setup to clear
    flags = -flags;					// get flags correct
  }
  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  systab->vol[volnum-1]->stats.dbset++;                 // update stats
  writing = 1;						// say we are writing
  while (systab->vol[volnum - 1]->writelock)		// check for write lock
  { i = sleep(5);					// wait a bit
    if (partab.jobtab->attention)
    { return -(ERRZLAST+ERRZ51);			// for <Control><C>
    }
  }							// end writelock check
  Get_GBDs(1);						// ensure this many
  s = Get_data(0);                                      // try to find that
  if ((s < 0) && (s != -ERRM7))                         // check for errors
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return (int) s;					// return error
  }
  i = ((int *)record)[1];				// get current flags
  if (clearit)
  { i = i & ~flags;					// clear flags
  }
  else
  { i = i | flags;					// set flags
  }
  ((int *)record)[1] = i;				// set back to GD
  if (blk[level]->dirty == (gbd *) 1)			// if reserved
  { blk[level]->dirty = blk[level];			// terminate list
    Queit();						// que for write
  }
  SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  return i;						// return current flags
}
コード例 #8
0
int
main()
{
    int *array = (int *)ShmAllocate(10*sizeof(int));
    array[0]=1;
    int x = Fork();
    int id = SemGet(SEMKEY);
    if(x == 0) {
        SemOp(id, -1);
        PrintChar('C');
        array[0]=10;
        SemOp(id, 1);
    } else {
        Join(x);
        SemOp(id, -1);
        PrintChar('P');
        PrintInt(array[0]);
        SemOp(id, 1);
    }
}
コード例 #9
0
ファイル: db_view.c プロジェクト: pahihu/mumps
struct GBD *DB_ViewGet(int vol, int block)		// return gbd for blk
{ short s;						// for func
  if ((block < 1) || (block > systab->vol[vol-1]->vollab->max_block))
  { return NULL;					// validate
  }
  level = 0;						// where it goes
  volnum = vol;						// need this
  writing = 0;						// clear this
  s = SemOp(SEM_GLOBAL, READ);				// write lock
  if (s < 0)						// check error
  { return NULL;					// quit if so
  }
  s = Get_block(block);					// get it
  if (s >= 0)
  { blk[level]->last_accessed = MTIME(0)+86400;		// push last access
  }
  if (curr_lock)
  { SemOp( SEM_GLOBAL, -curr_lock);			// unlock the globals
  }
  return (s < 0) ? NULL : blk[level];			// return whatever
}
コード例 #10
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
int DB_GetFlags(mvar *var)	                       	// Get flags
{ short s;						// for returns
  int i;						// a handy int

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  s = Get_data(0);					// try to find that
  if ((s < 0) && (s != -ERRM7))				// check for errors
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    return s;						// and return the error
  }
  i = ((int *) record)[1];				// get the value
  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  return i;						// return the flags
}
コード例 #11
0
ファイル: queue.c プロジェクト: irfanhudda/nachos-assign3
int
Enqueue (int x, int id)
{
   int y;

   SemOp(semid, -1);
   while (array[SIZE+2] == SIZE) {
      SemOp(stdoutsemid, -1);
      PrintString("Enqueuer ");
      PrintInt(id);
      PrintString(": waiting on queue full.");
      PrintChar('\n');
      SemOp(stdoutsemid, 1);
      CondOp(notFullid, COND_OP_WAIT, semid);
   }
   array[array[SIZE+1]] = x;
   y = array[SIZE+1];
   array[SIZE+1] = (array[SIZE+1] + 1)%SIZE;
   array[SIZE+2]++;
   CondOp(notEmptyid, COND_OP_SIGNAL, semid);
   SemOp(semid, 1);
   return y;
}
コード例 #12
0
ファイル: queue.c プロジェクト: irfanhudda/nachos-assign3
int
Dequeue (int id, int *y)
{
   int x;

   SemOp(semid, -1);
   while (array[SIZE+2] == 0) {
      SemOp(stdoutsemid, -1);
      PrintString("Dequeuer ");
      PrintInt(id);
      PrintString(": waiting on queue empty.");
      PrintChar('\n');
      SemOp(stdoutsemid, 1);
      CondOp(notEmptyid, COND_OP_WAIT, semid);
   }
   x = array[array[SIZE]];
   (*y) = array[SIZE];
   array[SIZE] = (array[SIZE] + 1)%SIZE;
   array[SIZE+2]--;
   CondOp(notFullid, COND_OP_SIGNAL, semid);
   SemOp(semid, 1);
   return x;
}
コード例 #13
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
void DB_StopJournal(int vol, u_char action)		// Stop journal
{ jrnrec jj;

  volnum = vol;						// set common var
  if (!systab->vol[vol - 1]->vollab->journal_available) // if no journal
  { return;						// just exit
  }
  while (SemOp( SEM_GLOBAL, WRITE))
  { sleep(1);
  }
  jj.action = action;
  jj.uci = 0;
  jj.name.var_qu = 0;
  jj.slen = 0;
  DoJournal(&jj, NULL);
  systab->vol[vol - 1]->vollab->journal_available = 0;
  return;
}
コード例 #14
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Set(mvar *var, cstring *data)	         	// set global data
{ short s;						// for returns
  int i;						// a handy int

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  i = 4 + db_var.slen + 2 + data->len;			// space reqd
  if (i & 3)						// if required
  { i += (4 - (i & 3));					// round up
  }
  i += 4;						// add Index
  if (i > (systab->vol[volnum-1]->vollab->block_size - 20)) // if too big
  { return -ERRM75;					// return an error
  }
  systab->vol[volnum-1]->stats.dbset++;                 // update stats
  writing = 1;						// say we are writing
  while (systab->vol[volnum - 1]->writelock)		// check for write lock
  { i = sleep(5);					// wait a bit
    if (partab.jobtab->attention)
    { return -(ERRZLAST+ERRZ51);			// for <Control><C>
    }
  }							// end writelock check

  i = systab->vol[volnum-1]->vollab->max_block >> 3;	// last map byte
  while (i)						// check from the end
  { if ((((u_char *) systab->vol[volnum - 1]->map)[i--]) == 0)
    { break;						// OK if byte is free
    }
  }

  if (!i)
  { return -(ERRZLAST+ERRZ11);				// complain if failed
  }

  s = Set_data(data);					// do the set

  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  return s;						// return the result
}
コード例 #15
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Get(mvar *var, u_char *buf)           		// get global data
{ short s;						// for returns

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  systab->vol[volnum-1]->stats.dbget++;                 // update stats
  s = Get_data(0);					// attempt to get it
  if (s >= 0)						// if worked
  { if (bcmp("$GLOBAL\0", &db_var.name.var_cu[0], 8) == 0) // if ^$G
    { s = itocstring(buf, *(u_int *) record);		// block number
    }
    else
    { s = mcopy(record->buf, buf, record->len);		// copy the data
    }
  }
  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  return s;						// return the count
}
コード例 #16
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Order(mvar *var, u_char *buf, int dir) 	// get next subscript
{ short s;						// for returns
  int i;						// a handy int
  int last_key;						// start of last key

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  systab->vol[volnum-1]->stats.dbord++;                 // update stats
  last_key = UTIL_Key_Last(&db_var);			// get start of last
  buf[0] = '\0';					// null terminate ret
  if (dir < 0)						// if it's backward
  { s = Get_data(-1);					// get the previous
    if ((s < 0) && (s != -ERRM7))			// check for errors
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return s;						// and return the error
    }
    if ((level == 0) && (s == -ERRM7) &&		// if no such global
	(bcmp(&db_var.name.var_cu[0], "$GLOBAL\0", 8)))	// and not ^$G()
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return 0;						// and return
    }
    Index--;                                          	// backup the Index
    if (Index < 10)                                   	// can't happen?
    { panic("DB_Order: Problem with negative direction");
    }
    chunk = (cstring *) &iidx[idx[Index]];             	// point at the chunk
    record = (cstring *) &chunk->buf[chunk->buf[1]+4];	// point at the dbc
  }							// end backwards
  else							// it's forward
  { db_var.key[db_var.slen++] = 255;			// force next key
    s = Get_data(0);					// try to find that
    if (s != -ERRM7)					// MUST be undefined
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return (s < 0) ? s : -(ERRMLAST+ERRZ61);		// and return the error
    }
    if ((level == 0) &&					// if no such global
	(bcmp(&db_var.name.var_cu[0], "$GLOBAL\0", 8)))	// and not ^$G()
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return 0;						// and return
    }
    if (Index > blk[level]->mem->last_idx)		// no more avbl
    { s = Locate_next();				// get next (if there)
      if (s < 0)					// failed?
      { if (curr_lock)					// if locked
        { SemOp( SEM_GLOBAL, -curr_lock);		// release global lock
        }
        return (s == -ERRM7) ? 0 : s;			// done
      }
    }
  }							// end forwards
  for (i = 10; i <= Index; i++)				// scan to current
  { chunk = (cstring *) &iidx[idx[i]];             	// point at the chunk
    bcopy(&chunk->buf[2], &keybuf[chunk->buf[0]+1],
	  chunk->buf[1]);				// update the key
    keybuf[0] = chunk->buf[0] + chunk->buf[1];		// and the size
  }

  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  if ((keybuf[0] < (last_key + 1)) ||
      (bcmp(&keybuf[1], db_var.key, last_key)))		// check for past it
  { return 0;						// done
  }
  i = 0;						// clear flag
  s = UTIL_Key_Extract(&keybuf[last_key+1], buf, &i);	// extract the key
  return s;						// return result
}
コード例 #17
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Compress(mvar *var, int flags)			// Compress global
{ int i;
  short s;
  int retlevel;						// the ACTUAL level

  flags &= 15;						// clear high bits
  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }

  bzero(rekey_blk, MAXREKEY * sizeof(u_int));           // clear that table
  bzero(rekey_lvl, MAXREKEY * sizeof(int));             // and that table

  bcopy(&db_var, var, sizeof(mvar));			// copy the data back
  s = Get_data(flags);					// get to level 'flags'
  retlevel = level;					// save real level
  if (!level)
  { return -ERRM7;					// give up if nosuch
  }
  chunk = (cstring *) &iidx[idx[10]];			// point at the first
  bcopy(&chunk->buf[1], &var->slen, chunk->buf[1]+1);	// save the real key

  while (TRUE)
  { bcopy(var, &db_var, sizeof(mvar));			// get next key
    writing = 0;					// flag we are reading

    while (systab->vol[volnum - 1]->writelock)		// check for write lock
    { i = sleep(5);					// wait a bit
      if (partab.jobtab->attention)
      { return -(ERRZLAST+ERRZ51);			// for <Control><C>
      }
    }							// end writelock check
    if (partab.jobtab->attention)
    { return -(ERRZLAST+ERRZ51);			// for <Control><C>
    }

    s = Get_data(retlevel);				// get the block
    if ((s == -ERRM7) && (!db_var.slen))		// if first node
    { s = 0;						// it exists
    }
    if (s == -ERRM7)					// if key changed
    { if (blk[level]->mem->right_ptr)			// if more
      { chunk = (cstring *) &iidx[idx[10]];		// point at the first
	bcopy(&chunk->buf[1], &db_var.slen, chunk->buf[1]+1); // save real key
	SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
	continue;					// go again
      }
      SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      return retlevel;					// all done, exit
    }
    if (s < 0)
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      return s;						// exit on error
    }
    if (!blk[level]->mem->right_ptr)			// if no more
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      if ((retlevel == 2) && (!db_var.slen))		// if only block lvl 2
      { s = Compress1();				// do that
	SemOp( SEM_GLOBAL, -curr_lock);			// release write lock
	if (s < 0)
	{ return s;					// exit on error
	}
      }
      return retlevel;					// all done, exit
    }
    level++;
    s = Get_block(blk[level - 1]->mem->right_ptr);
    if (s < 0)						// if error
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      return s;						// exit on error
    }
    i = ((blk[level-1]->mem->last_free*2 + 1 - blk[level-1]->mem->last_idx)*2)
      + ((blk[level]->mem->last_free*2 + 1 - blk[level]->mem->last_idx)*2);
    if (i < 1024)	// if REALLY not enough space (btw: make this a param)
    { chunk = (cstring *) &iidx[idx[10]];		// point at first in RL
      bcopy(&chunk->buf[1], &var->slen, chunk->buf[1]+1); // save the real key
      SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      continue;						// go again
    }
    level = retlevel;
    SemOp( SEM_GLOBAL, -curr_lock);			// release read lock
    s = Compress1();					// do that
    SemOp( SEM_GLOBAL, -curr_lock);			// release write lock
    if (s < 0)
    { return s;						// exit on error
    }
    if (!var->volset)					// if done
    { return retlevel;
    }
  }
}
コード例 #18
0
ファイル: queue.c プロジェクト: irfanhudda/nachos-assign3
int
main()
{
    array = (int*)ShmAllocate(sizeof(int)*(SIZE+3));  // queue[SIZE], head, tail, count
    int x, i, j, seminit = 1, y;
    int pid[NUM_DEQUEUER+NUM_ENQUEUER];

    for (i=0; i<SIZE; i++) array[i] = -1;
    array[SIZE] = 0;
    array[SIZE+1] = 0;
    array[SIZE+2] = 0;

    semid = SemGet(SEM_KEY1);
    SemCtl(semid, SYNCH_SET, &seminit);

    stdoutsemid = SemGet(SEM_KEY2);
    SemCtl(stdoutsemid, SYNCH_SET, &seminit);

    notFullid = CondGet(COND_KEY1);
    notEmptyid = CondGet(COND_KEY2);

    int temp;
    temp = -11;
    SemCtl(semid,SYNCH_GET,&temp);
    PrintInt(temp);
    for (i=0; i<NUM_DEQUEUER; i++) {
       x = Fork();
       if (x == 0) {
          for (j=0; j<NUM_DEQUEUE_OP; j++) {
             x = Dequeue (i, &y);
             SemOp(stdoutsemid, -1);
             PrintString("Dequeuer ");
             PrintInt(i);
             PrintString(": Got ");
             PrintInt(x);
             PrintString(" from slot ");
             PrintInt(y);
             PrintChar('\n');
             SemOp(stdoutsemid, 1);
          }
          Exit(DEQUEUE_EXIT_CODE);
       }
       pid[i] = x;
    }
    
    for (i=0; i<NUM_ENQUEUER; i++) {
       x = Fork();
       if (x == 0) {
          x = i*NUM_ENQUEUE_OP;
          for (j=0; j<NUM_ENQUEUE_OP; j++) {
             y = Enqueue (x+j, i);
             SemOp(stdoutsemid, -1);
             PrintString("Enqueuer ");
             PrintInt(i);
             PrintString(": Inserted ");
             PrintInt(x+j);
             PrintString(" in slot ");
             PrintInt(y);
             PrintChar('\n');
             SemOp(stdoutsemid, 1);
          }
          Exit(ENQUEUE_EXIT_CODE);
       }
       pid[i+NUM_DEQUEUER] = x;
    }

    for (i=0; i<NUM_DEQUEUER+NUM_ENQUEUER; i++) {
       x = Join(pid[i]);
       SemOp(stdoutsemid, -1);
       PrintString("Parent joined with ");
       PrintInt(pid[i]);
       PrintString(" having exit code ");
       PrintInt(x);
       PrintChar('\n');
       SemOp(stdoutsemid, 1);
    }
    SemCtl(semid, SYNCH_REMOVE, 0);
    SemCtl(stdoutsemid, SYNCH_REMOVE, 0);
    CondRemove(notFullid);
    CondRemove(notEmptyid);

    return 0;
}
コード例 #19
0
ファイル: init_run.c プロジェクト: pahihu/mumps
//****************************************************************************
// Attach to an environment - switches are:
//                            x = xecute command                Opt
//                            e = environment (UCI)             Opt
int INIT_Run( char *file,                       // database file
              char *env,                        // environment (UCI)
              char *cmd)                        // command

{ int i;                                        // an int
  int dbfd = 0;                                 // database file descriptor
  int ret = 0;					// return value
  int env_num = 1;				// startup environemnt number
  var_u tmp;					// temp descriptor
  uci_tab *uci_ptr;				// for uci search
  int pid;					// job number
  int ssp = 0;					// string stack ptr
  int asp = 0;					// address stack ptr
  mvar *var;					// a variable pointer
  cstring *cptr;				// a handy pointer
  cstring *sptr;                                // cstring ptr
  short s;					// for functions
  short start_type = TYPE_RUN;			// how we started
  gid_t gidset[MAX_GROUPS];			// for getgroups()
  struct termios tty_settings;			// man 4 termios

start:
#if defined(__APPLE__) || defined(__FreeBSD__)
  srandomdev();					// randomize
#endif

  partab.jobtab = (jobtab *) NULL;		// clear jobtab pointer
  dbfd = open(file, O_RDONLY);                  // open the database for read
  if (dbfd < 0) return (errno);                 // if that failed
  // i = fcntl(dbfd, F_NOCACHE, 1);
  if (start_type == TYPE_RUN)			// if not from JOB
  { i = UTIL_Share(file);                       // attach to shared mem
    if (i != 0) return(i);                      // quit on error
  }
  if (env != NULL)				// passed in uci ?
  { env_num = 0;				// clear uci number
    uci_ptr = &systab->vol[0]->vollab->uci[0];	// get ptr to uci table
    //tmp.var_qu = 0;				// zero entire name
    X_Clear(tmp.var_xu);			// zero entire name
    for (i = 0; i < MAX_NAME_BYTES; i++)	// copy in name
    { if (env[i] == '\0') break;		// done at null
      tmp.var_cu[i] = env[i];			// copy character
    }
    for (i = 0; i < UCIS; i++)			// scan all ucis
     //if (uci_ptr[i].name.var_qu == tmp.var_qu)	// if we have a match
     if (X_EQ(uci_ptr[i].name.var_xu, tmp.var_xu))      // if we have a match
     { env_num = i + 1;				// save it
       break;					// and exit loop
     }
    if (env_num == 0)
    { ret = ENOENT;				// complain on fail
      goto exit;				// and exit
    }
  }

  pid = (int) getpid();				// get process id
  for (i = 0; i < systab->maxjob; i++)		// scan the slots
  { ret = systab->jobtab[i].pid;		// get pid
    if ((ret != pid) && (ret))			// if one there and not us
    { if (kill(ret, 0))				// check the job
      { if (errno == ESRCH)			// doesn't exist
        { ret = CleanJob(i + 1);		// zot if not there
	  if (ret == 0)                         // success ?
            break;			        //   have at least one
        }
      }
    }
    else					// it's free or ours
    { break;					// quit
    }
  }

  ret = SemOp(SEM_SYS, -systab->maxjob);	// lock systab
  if (ret < 0) goto exit;			// give up on error
  for (i = 0; i < systab->maxjob; i++)		// look for a free slot
  { if (((systab->jobtab[i].pid == 0) &&	// this one ?
	 (start_type == TYPE_RUN))    ||
	((systab->jobtab[i].pid == pid) &&	// or already done (JOB)
	 (start_type == TYPE_JOB)))
    { bzero(&systab->jobtab[i], sizeof(jobtab)); // yes - zot the lot
      partab.jobtab = &systab->jobtab[i];	// and save our jobtab address
      partab.jobtab->pid = pid;			// copy in our pid
      break;					// end loop
    }
  }
  ret = SemOp(SEM_SYS, systab->maxjob);		// unlock systab
  if (partab.jobtab == NULL)			// if that failed
  { ret = ENOMEM;				// error message
    goto exit;					// and exit
  }

  partab.jobtab->user = (short) getuid();	// get user number

  if ((partab.jobtab->user == systab->start_user) || // if he started it
      (partab.jobtab->user == 0))		// or is root
  { partab.jobtab->priv = 1;			// say yes
  }
  else 
  { if (systab->maxjob == 1)			// if single job
    { ret = ENOMEM;				// error message
      partab.jobtab = NULL;			// clear this
      goto exit;				// and exit
    }

    i = getgroups(MAX_GROUPS, gidset);		// get groups
    if (i < 0)					// if an error
    { ret = errno;				// get the error
      goto exit;				// and exit
    }
    while (i > 0)				// for each group
    { if (gidset[i - 1] == PRVGRP)		// if it's "wheel" or "admin"
      { partab.jobtab->priv = 1;		// say yes
        break;					// and exit
      }
      i--;					// decrement i
    }
  }

  partab.jobtab->precision = systab->precision;	// decimal precision

  partab.jobtab->uci = env_num;			// uci number
  partab.jobtab->vol = 1;			// volset
  partab.jobtab->luci = env_num;		// uci number
  partab.jobtab->lvol = 1;			// volset
  partab.jobtab->ruci = env_num;		// uci number
  partab.jobtab->rvol = 1;			// volset

  partab.jobtab->start_len =
    Vhorolog(partab.jobtab->start_dh);		// store start date/time

  partab.jobtab->dostk[0].type = TYPE_RUN;	// ensure slot 0 has a value

  failed_tty = tcgetattr ( 0, &tty_settings );
  i = SQ_Init();				// have seqio setup chan 0

  systab->last_blk_used[partab.jobtab - systab->jobtab] = 0;
						// clear last global block
  partab.debug = 0;				// clear debug flag
  partab.sstk_start = &sstk[0];			// address of sstk
  partab.sstk_last =  &sstk[MAX_SSTK];		// and the last char
  partab.varlst = NULL;				// used by compiler

  partab.vol_fds[0] = dbfd;			// make sure fd is right

  ST_Init();					// initialize symbol table

  if ((systab->vol[0]->vollab->journal_available) &&
      (systab->vol[0]->vollab->journal_requested)) // if journaling
  { partab.jnl_fds[0] = open(systab->vol[0]->vollab->journal_file, O_RDWR);
    if (partab.jnl_fds[0] < 0)
    { fprintf(stderr, "Failed to open journal file %s\nerrno = %d\n",
		systab->vol[0]->vollab->journal_file, errno);
      ret = -1;
      if (cmd != NULL) goto exit;
    }
    else
    { // i = fcntl(dbfd, F_NOCACHE, 1);
    }
  }

  if (cmd != NULL)				// command specified ?
  { source_ptr = (u_char *) cmd;		// where the code is
    cptr = (cstring *) &sstk[ssp];		// where the compiled goes
    comp_ptr = cptr->buf;			// the data bit
    parse();
    *comp_ptr++ = CMQUIT;			// add the quit
    *comp_ptr++ = ENDLIN;			// JIC
    *comp_ptr++ = ENDLIN;			// JIC
    i = &comp_ptr[0] - &cptr->buf[0];		// get number of bytes
    cptr->len = i;				// save for ron
    ssp = ssp + i + sizeof(short) + 1;		// point past it
    mumpspc = &cptr->buf[0];			// setup the mumpspc
    partab.jobtab->dostk[0].routine = (u_char *) cmd; 	// where we started
    partab.jobtab->dostk[0].pc = mumpspc;	// where we started
    partab.jobtab->dostk[0].symbol = NULL;	// nowhere
    partab.jobtab->dostk[0].newtab = NULL;	// nowhere
    partab.jobtab->dostk[0].endlin = mumpspc + i - 4; // ENDLIN
    //partab.jobtab->dostk[0].rounam.var_qu = 0;// zero the routine name
    X_Clear(partab.jobtab->dostk[0].rounam.var_xu);	// zero the routine name
    partab.jobtab->dostk[0].vol = partab.jobtab->vol; // current volume
    partab.jobtab->dostk[0].uci = partab.jobtab->uci; // current uci
    partab.jobtab->dostk[0].line_num = 0;	// no line number
    partab.jobtab->dostk[0].type = start_type;	// how we started
    partab.jobtab->dostk[0].estack = 0;		// estack offset
    partab.jobtab->dostk[0].level = 0;		// where we started
    partab.jobtab->dostk[0].flags = 0;		// no flags
    partab.jobtab->dostk[0].savasp = asp;	// address stack ptr
    partab.jobtab->dostk[0].savssp = ssp;	// string stack
    partab.jobtab->dostk[0].asp = asp;		// address stack ptr
    partab.jobtab->dostk[0].ssp = ssp;		// string stack

    partab.jobtab->attention = 0;
    partab.jobtab->trap = 0;
    partab.jobtab->async_error = 0;
    isp = 0;					// clear indirect pointer
    s = run(asp, ssp);
    if (s == OPHALT) goto exit;			// look after halt
    if (s == JOBIT) goto jobit;			// look after JOB
    partab.jobtab->io = 0;			// force chan 0
    var = (mvar *) &sstk[0];			// space to setup a var
    X_set("$ECODE\0\0", &var->name.var_cu[0], 8);
    var->volset = 0;
    var->uci = UCI_IS_LOCALVAR;
    var->slen = 0;				// setup for $EC
    cptr = (cstring *) &sstk[sizeof(mvar)];	// for result
    bcopy("$ECODE=", cptr->buf, 7);
    s = ST_Get(var, &cptr->buf[7]);
    if (s > 1) 					// ignore if nothing there
    { cptr->len = s + 7;
      s = SQ_WriteFormat(SQ_LF);		// new line
      s = SQ_Write(cptr);			// write the prompt
      s = SQ_WriteFormat(SQ_LF);		// new line
      cptr = (cstring *) (((u_char *) cptr) + 8);
      if (cptr->buf[0] != 'U')
      { cptr->len = 4;				// max error size
        cptr->len = Xcall_errmsg((char *) cptr->buf, cptr, cptr); // cvt to str
        s = SQ_Write(cptr);			// write the error
        s = SQ_WriteFormat(SQ_LF);		// new line
      }
      ret = ESRCH;				// set an error for exit
    }
    goto exit;					// and halt
  }

  while (TRUE)					// forever
  { sptr = (cstring *) &sstk[0];		// front of string stack
    asp = 0;					// zot address stack
    ssp = 0;					// and the string stack
    bcopy("M> ", sptr->buf, 3);			// copy in the prompt
    sptr->buf[3] = '\0';			// null terminate
    sptr->len = 3;				// and the length
    partab.jobtab->io = 0;			// force chan 0
    if (partab.jobtab->seqio[0].dx)		// if not at right margin
    { s = SQ_WriteFormat(SQ_LF);		// new line
      if (s < 0) ser(s);			// check for error
    }
    s = SQ_Write(sptr);				// write the prompt
    if (s < 0) ser(s);				// check for error
    s = SQ_Read(sptr->buf, -1, -1);		// get a string
    i = attention();				// check signals
    if (i == OPHALT) break;			// exit on halt
    if (i == -(ERRZ51+ERRMLAST))		// control c
      controlc();				// say
    if (s < 0)
    { ser(s);					// complain on error
      s = 0;
    }
    sptr->len = s;				// save the length
    if (s == 0) continue;			// ignore null
    astk[asp++] = (u_char *) sptr;		// save address of string
    ssp = ssp + s + sizeof(short) + 1;		// point past it
    s = SQ_WriteFormat(SQ_LF);			// new line
    if (s < 0) ser(s);				// check for error
    source_ptr = sptr->buf;			// where the code is
    cptr = (cstring *) &sstk[ssp];		// where the compiled goes
    comp_ptr = cptr->buf;			// the data bit
    parse();
    *comp_ptr++ = CMQUIT;			// add the quit
    *comp_ptr++ = ENDLIN;			// JIC
    *comp_ptr++ = ENDLIN;			// JIC
    i = &comp_ptr[0] - &cptr->buf[0];		// get number of bytes
    cptr->len = i;				// save for ron
    ssp = ssp + i + sizeof(short) + 1;		// point past it

    mumpspc = &cptr->buf[0];			// setup the mumpspc
    partab.jobtab->dostk[0].routine = sptr->buf; // where we started
    partab.jobtab->dostk[0].pc = mumpspc;	// where we started
    partab.jobtab->dostk[0].symbol = NULL;	// nowhere
    partab.jobtab->dostk[0].newtab = NULL;	// nowhere
    partab.jobtab->dostk[0].endlin = mumpspc + i - 4; // ENDLIN
    //partab.jobtab->dostk[0].rounam.var_qu = 0;// zero the routine name
    X_Clear(partab.jobtab->dostk[0].rounam.var_xu);// zero the routine name
    partab.jobtab->dostk[0].vol = partab.jobtab->vol; // current volume
    partab.jobtab->dostk[0].uci = partab.jobtab->uci; // current uci
    partab.jobtab->dostk[0].line_num = 0;	// no line number
    partab.jobtab->dostk[0].type = TYPE_RUN;	// how we started
    partab.jobtab->dostk[0].estack = 0;		// estack offset
    partab.jobtab->dostk[0].level = 0;		// where we started
    partab.jobtab->dostk[0].flags = 0;		// no flags
    partab.jobtab->dostk[0].savasp = asp;	// address stack ptr
    partab.jobtab->dostk[0].savssp = ssp;	// string stack
    partab.jobtab->dostk[0].asp = asp;		// address stack ptr
    partab.jobtab->dostk[0].ssp = ssp;		// string stack

    partab.jobtab->attention = 0;
    partab.jobtab->trap = 0;
    partab.jobtab->async_error = 0;
    isp = 0;					// clear indirect pointer
    s = run(asp, ssp);
    if (s == JOBIT) goto jobit;			// look after JOB
    if (s == OPHALT) break;			// exit on halt
    partab.jobtab->io = 0;			// force chan 0
    if (s == -(ERRZ51+ERRMLAST))		// control c
      controlc();				// say
    else if (s < 0) ser(s);
    partab.jobtab->error_frame = 0;		// and that one
    var = (mvar *) &sstk[0];			// space to setup a var
    X_set("$ECODE\0\0", &var->name.var_cu[0], 8);
    var->volset = 0;
    var->uci = UCI_IS_LOCALVAR;
    var->slen = 0;				// setup for $EC
    cptr = (cstring *) &sstk[sizeof(mvar)];	// for result
    bcopy("$ECODE=", cptr->buf, 7);
    s = ST_Get(var, &cptr->buf[7]);
    if (s < 1) continue;			// ignore if nothing there
    cptr->len = s + 7;
    s = SQ_Write(cptr);				// write the prompt
    if (s < 0) ser(s);				// check for error
    s = SQ_WriteFormat(SQ_LF);			// new line
    if (s < 0) ser(s);				// check for error
    s = ST_Kill(var);				// dong $EC
    cptr = (cstring *) (((u_char *) cptr) + 8);
    if (cptr->buf[0] != 'U')
    { cptr->len = 4;				// max error size
      cptr->len = Xcall_errmsg((char *) cptr->buf, cptr, cptr); // cvt to str
      s = SQ_Write(cptr);			// write the error
      if (s < 0) ser(s);			// check for error
      s = SQ_WriteFormat(SQ_LF);		// new line
    }
  }						// end command level loop

exit:						// general exit code
  if (partab.jobtab != NULL)			// if we have a jobtab
    CleanJob(0);				// remove all locks etc
  i = shmdt(systab);                       // detach the shared mem
  if (dbfd)
    i = close(dbfd);                            // close the database
  if (!failed_tty)				// reset terminal if possible
  { failed_tty = tcsetattr ( 0, TCSANOW, &tty_settings );
  }
  if (start_type == TYPE_JOB) return 0;		// no error from JOB
  return ret;                                  	// and exit

jobit:						// code for JOB
  start_type = TYPE_JOB;			// what we are doing
  env_num = partab.jobtab->ruci;		// remember (current) rou uci
  cmd = (char *) &sstk[0];			// where the command is
  ssp = strlen((const char *) sstk);		// protect original command
  isp = 0;					// clear all these
  asp = 0;
  ret = 0;
  env = NULL;
  goto start;					// go do it
}
コード例 #20
0
int main (int argc, char *argv []) {
    key_t key = ftok (argv [0], 0);
    semid = semget (key, nsems, 0644 | IPC_CREAT | IPC_EXCL);
    
    if (semid >= 0) { //got it first
        SemInit();
    }
    else if (errno == EEXIST) {  //someone else got it first
        
        semid = semget (key, nsems, 0);
        if (semid < 0) {
            fprintf (stderr, "Failed to open semaphore\n");
            semctl (semid, 0, IPC_RMID, NULL);
            shmdt (shared);
            exit(EXIT_FAILURE);
        }
        unsigned short *ptr = (unsigned short *) 
                            calloc (nsems, sizeof (unsigned short));
        semctl (semid, mutex, GETALL, ptr);
        if (ptr [mutex] != 1 || ptr [full] != 0 || ptr [empty] != buf_num) {
            SemInit();
        }
    }
    else {
            semctl (semid, 0, IPC_RMID, NULL);
            shmdt (shared);
            perror("\nFailed to create semaphore.");
            semctl (semid, 0, IPC_RMID, NULL);
            shmdt (shared);
            exit(EXIT_FAILURE);
    }
    
    int shmid = shmget (key, sizeof (in_data), 0644 | IPC_CREAT);
    if (shmid == -1) {
        perror("\nFailed to allocate shared memory.");
        semctl (semid, 0, IPC_RMID, NULL);
        shmdt (shared);
        exit(EXIT_FAILURE);
    }
    shared = (in_data*) shmat (shmid, NULL, 0);
    
    if (argc > 1) {
        SemOpMul (semid, ping1,  1, SEM_UNDO);
        SemOpMul (semid, ping2,  1, SEM_UNDO);
        SemOpMul (semid, init1, -1, SEM_UNDO);
        SemOpMul (semid, init2,  0, 0);
        //writer (Producer)
        int src = open (argv [1], O_RDONLY, 0);
        int ret_num = 1;
        while (ret_num > 0) {
            SemOp ('P', semid, empty, 0, ping1);
            SemOp ('P', semid, mutex, 0, ping1);
            ret_num = read (src, shared -> buffer, buf_size);
            shared -> num = ret_num;
            SemOp ('V', semid, mutex, 0, ping1);
            SemOp ('V', semid, full,  0, ping1);
        }
    } 
    else {
        //reader (Consumer)
        SemOpMul (semid, ping2, 1, SEM_UNDO);
        SemOpMul (semid, ping1, 1, SEM_UNDO);
        SemOpMul (semid, init2, -1, SEM_UNDO);
        SemOpMul (semid, init1,  0, 0);
        while (1) {
            SemOp ('P', semid, full,  0, ping2);
            SemOp ('P', semid, mutex, 0, ping2);
            write (1, shared -> buffer, shared -> num);
            fflush (stdout);
            SemOp ('V', semid, mutex, 0, ping2);
            SemOp ('V', semid, empty, 0, ping2);
            
        }
    }
    semctl (semid, 0, IPC_RMID, NULL);
    shmdt (shared);
    return 0;
}
コード例 #21
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Kill(mvar *var)	                       	// remove sub-tree
{ short s;						// for returns
  int i;						// a handy int

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  systab->vol[volnum-1]->stats.dbkil++;                 // update stats
  while (systab->vol[volnum - 1]->writelock)		// check for write lock
  { i = sleep(5);					// wait a bit
    if (partab.jobtab->attention)
    { return -(ERRZLAST+ERRZ51);			// for <Control><C>
    }
  }							// end writelock check

  s = Get_data(0);					// attempt to get it
  if (((s == -ERRM7) && (level == 0)) ||		// if nosuch
      ((s < 0) && (s != -ERRM7)))			// or an error
  { if (curr_lock)					// if locked
    { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
    }
    if (s == -ERRM7)					// if undefined
    { s = 0;						// that is OK
    }
    return s;						// nothing to do
  }

  if ((s == -ERRM7) && (db_var.slen))			// if undefined
  { if (Index <= blk[level]->mem->last_idx)		// and still in block

    { if ((db_var.slen > keybuf[0]) ||			// found smaller key
          (bcmp(&keybuf[1], db_var.key, db_var.slen)))	// not a descendant?
      { if (curr_lock)					// if locked
        { SemOp( SEM_GLOBAL, -curr_lock);		// release global lock
        }
        return 0;					// nothing to do
      }
    }							// end still in block
    else
    { s = Locate_next();				// point at next block
      if (!s)						// found one
      { if ((db_var.slen > keybuf[0]) ||		// found smaller key
            (bcmp(&keybuf[1], db_var.key, db_var.slen))) // not a descendant?
        { s = -ERRM7;					// flag for later
        }
      }
      if (s < 0)					// no such or error
      { if (curr_lock)					// if locked
        { SemOp( SEM_GLOBAL, -curr_lock);		// release global lock
        }
	if (s == -ERRM7)
	{ s = 0;
	}
        return 0;					// nothing to do
      }
    }
  }
  s = Kill_data();					// do the kill

  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  return s;						// return the result
}
コード例 #22
0
ファイル: db_main.c プロジェクト: codeaudit/mumps
short DB_Query(mvar *var, u_char *buf, int dir) 	// get next key
{ short s;						// for returns
  int i;						// a handy int

  s = Copy2local(var);					// get local copy
  if (s < 0)
  { return s;						// exit on error
  }
  systab->vol[volnum-1]->stats.dbqry++;                 // update stats
  if (dir < 0)						// if it's backward
  { s = Get_data(-1);					// get the previous
    if ((s < 0) && (s != -ERRM7))			// check for errors
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return s;						// and return the error
    }
    if ((level == 0) && (s == -ERRM7))			// if no such global
    { buf[0] = '\0';					// null terminate ret
      if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return 0;						// and return
    }
    Index--;                                          	// backup the Index
    if (Index < 10)                                   	// can't happen?
    { panic("DB_Query: Problem with negative direction");
    }
    chunk = (cstring *) &iidx[idx[Index]];             	// point at the chunk
    record = (cstring *) &chunk->buf[chunk->buf[1]+4];	// point at the dbc
    if ((!chunk->buf[0]) && (!chunk->buf[1]) &&		// if first node
        ((partab.jobtab->last_block_flags & GL_TOP_DEFINED) == 0))
    { buf[0] = '\0';					// null terminate ret
      if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return 0;						// and return
    }
  }							// end backwards
  else							// it's forward
  { s = Get_data(0);					// try to find that
    if ((s < 0) && (s != -ERRM7))			// check for errors
    { if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return s;						// and return the error
    }
    if ((level == 0) && (s == -ERRM7))			// if no such global
    { buf[0] = '\0';					// null terminate ret
      if (curr_lock)					// if locked
      { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
      }
      return 0;						// and return
    }
    if ((s < 0) && (!db_var.slen))
    { Index++;
    }
    if ((Index > blk[level]->mem->last_idx) || (s >= 0)) // want next one
    { s = Locate_next();				// point at next
      if (s < 0)					// not found or error
      { if (curr_lock)					// if locked
        { SemOp( SEM_GLOBAL, -curr_lock);		// release global lock
        }
        buf[0] = '\0';					// null terminate ret
	if (s == -ERRM7)				// undefined?
	{ s = 0;					// yes - clear it
	}
        return s;					// done
      }
    }
  }

  for (i = 10; i <= Index; i++)				// scan to current
  { chunk = (cstring *) &iidx[idx[i]];             	// point at the chunk
    bcopy(&chunk->buf[2], &keybuf[chunk->buf[0]+1],
	  chunk->buf[1]);				// update the key
    keybuf[0] = chunk->buf[0] + chunk->buf[1];		// and the size
  }
  if (curr_lock)					// if locked
  { SemOp( SEM_GLOBAL, -curr_lock);			// release global lock
  }
  db_var.uci = var->uci;				// copy
  db_var.volset = var->volset;				//   original & new
  db_var.name.var_qu = var->name.var_qu;		//      data
  db_var.slen = keybuf[0];				//         to
  bcopy(&keybuf[1], &db_var.key[0], keybuf[0]);		//           db_var
  return UTIL_String_Mvar(&db_var, buf, 9999);		// convert and return
}
コード例 #23
0
ファイル: semop.c プロジェクト: nawhizz/KAIT
int CBD1 
semop(int semid, struct sembuf semoparray[], size_t nsops)
{
	int	i;
	int	piid;
	DWORD	procid;
	HANDLE	hIpct = NULL;
	IPCT	*ipct = NULL;

//	StartIPCD();
	if (semid<0 || semid>=MAXNOOFIPC)
	{
		errno=EINVAL;
		return -1;
	}

	if (GetIPCT(&hIpct, &ipct)<0)
	{
		errno=EFAULT;
		return -1;
	}

	if (ipct->semt[semid].key<0)
	{
		procid=GetCurrentProcessId();
		piid=FindPINFO(OPT_SEM, procid, ipct);
		if (piid>=0)
		{
			for (i=0; i<MAXNSEM; i++)
				ipct->pseminfo[piid].semadj[semid][i]=0;
			ipct->pseminfo[piid].semid[semid]=0;
			InitPINFO(OPT_SEM, piid, ipct);
		}

		errno=EINVAL;
		FreeIPCT(hIpct, ipct);
		return -1;
	}

	procid=GetCurrentProcessId();
	piid=FindPINFO(OPT_SEM, procid, ipct);
	if (piid<0)
	{
		piid=GetEmptyPINFO(OPT_SEM, ipct);
		if (piid<0)
		{
			errno=ENOSPC;
			FreeIPCT(hIpct, ipct);
			return -1;
		}
		ipct->pseminfo[piid].procid=procid;
//		ipct->pseminfo[piid].semid[semid]=1;
	}

	for (i=0; i<(int)nsops; i++)
	{
		if (SemOp(semid, &semoparray[i], procid, piid, ipct)<0)
		{
//			ipct->pseminfo[piid].semid[semid]=0;
//			for (j=0; j<MAXNSEM; j++)
//				ipct->pseminfo[piid].semadj[semid][j]=0;
//			InitPINFO(OPT_SEM, piid, ipct);
			FreeIPCT(hIpct, ipct);
			return -1;
		}
	}
//	ipct->pseminfo[piid].semid[semid]=0;
//	for (j=0; j<MAXNSEM; j++)
//		ipct->pseminfo[piid].semadj[semid][j]=0;
//	InitPINFO(OPT_SEM, piid, ipct);
	FreeIPCT(hIpct, ipct);

	return 0;
}