Example #1
0
LogEntry* stasis_log_impl_in_memory_reserve_entry(struct stasis_log_t* log, size_t sz) {
  stasis_log_impl_in_memory * impl = (stasis_log_impl_in_memory *)log->impl;
  /** Use calloc since the entry might not be packed in memory;
      otherwise, we'd leak uninitialized bytes to the log. */

  LogEntry * e = (LogEntry*)calloc(1,sz);

  lsn_t bufferOffset;
  int done = 0;
  int blockCount = 0;
  writelock(impl->flushedLSN_lock, 0);
  writelock(impl->globalOffset_lock,0);
  do{
    bufferOffset = impl->nextAvailableLSN - impl->globalOffset;
    if(bufferOffset >= impl->bufferLen) {
      if(2 * impl->bufferLen > impl->maxLen) {
        unlock(impl->globalOffset_lock);
        unlock(impl->flushedLSN_lock);
        blockCount++;
        if(blockCount == 100) {
          fprintf(stderr, "ERROR: Log blocked waiting to truncate, but truncation is not succeeding.\n"); fflush(stderr);
          abort();
        }
        stasis_truncation_truncate(impl->trunc, 1);
        writelock(impl->flushedLSN_lock, 0);
        writelock(impl->globalOffset_lock, 0);
      } else {
        impl->bufferLen *= 2;
        impl->buffer = stasis_realloc(impl->buffer, impl->bufferLen, LogEntry *);
      }
    } else {
      done = 1;
    }
  } while (!done);
Example #2
0
static lsn_t stasis_log_impl_in_memory_next_available_lsn(stasis_log_t * log) {
  stasis_log_impl_in_memory * impl = (stasis_log_impl_in_memory *)log->impl;
  writelock(impl->flushedLSN_lock,0);
  writelock(impl->globalOffset_lock,0);
  lsn_t ret = impl->nextAvailableLSN;
  unlock(impl->globalOffset_lock);
  unlock(impl->flushedLSN_lock);
  return ret;
}
Example #3
0
void * request(DfaSet * dfaSet, state_name start_state, char * recipient_addr, state_machine_id recipient_machine_id, Message * message) {
  StateMachine * initial_sm;
  state_machine_id machine_id;
  void * ret;
  writelock(dfaSet->lock, 600);

  initial_sm = allocSmash(dfaSet->smash);
  if(initial_sm == NULL) {
    return NULL;
  }

  assert(start_state != NULL_STATE);
  
  if(message != NULL) {
    
    memcpy(&(initial_sm->message), message, sizeof(Message));
  }
  
  initial_sm->current_state = start_state;
  initial_sm->message.from_machine_id = initial_sm->machine_id;
  initial_sm->message.to_machine_id = recipient_machine_id;
  initial_sm->message.type = start_state;

  char * initiator;
  {
    int err = asprintf(&initiator, "%s:%d", dfaSet->networkSetup.localhost, dfaSet->networkSetup.localport);
    assert(err != -1);
  }
  strcpy(initial_sm->message.initiator, initiator);
  free(initiator);
  //  printf("Set message initiator to %s\n", initial_sm->message.initiator); fflush(stdout);
  initial_sm->message.initiator_machine_id = initial_sm->machine_id;

  strcpy(initial_sm->message_recipient, recipient_addr);
  machine_id = initial_sm->machine_id;
  writeunlock(dfaSet->lock);

  ret = run_request(dfaSet, machine_id);

  writelock(dfaSet->lock, machine_id); 
  assert(initial_sm == getSmash(dfaSet->smash, machine_id));
  if(message != NULL) {

    memcpy(message, &(initial_sm->message), sizeof(Message));
  }

  freeSmash(dfaSet->smash, initial_sm->machine_id);
  writeunlock(dfaSet->lock);

  return ret;
}
Example #4
0
size_t dataPage::write_bytes(const byte * buf, ssize_t remaining, Page ** latch_p) {
    if(latch_p) {
        *latch_p  = NULL;
    }
    recordid chunk = calc_chunk_from_offset(write_offset_);
    if(chunk.size > remaining) {
        chunk.size = remaining;
    }
    if(chunk.page >= first_page_ + page_count_) {
        chunk.size = 0; // no space (should not happen)
    } else {
        Page *p = alloc_ ? alloc_->load_page(xid_, chunk.page) : loadPage(xid_, chunk.page);
        assert(chunk.size);
        memcpy(data_at_offset_ptr(p, chunk.slot), buf, chunk.size);
        stasis_page_lsn_write(xid_, p, alloc_->get_lsn(xid_));
        if(latch_p && !*latch_p) {
            writelock(p->rwlatch,0);
            *latch_p = p;
        } else {
            releasePage(p);
        }
        write_offset_ += chunk.size;
    }
    return chunk.size;
}
Example #5
0
void * worker_loop(void * arg_void) {

  WorkerLoopArgs * arg = arg_void;
  
  StateMachine * stateMachine;
  DfaSet * dfaSet = arg->dfaSet;
  state_machine_id machine_id = arg->machine_id;
  readlock(dfaSet->lock, machine_id);

  DEBUG("Worker loop: %ld\n", machine_id);
  
  stateMachine = getSmash(dfaSet->smash, machine_id);

  assert(stateMachine->machine_id == machine_id);

  if(pthread_detach(stateMachine->worker_thread) != 0) {
    perror("pthread_detach");
  }

  readunlock(dfaSet->lock);
  inner_worker_loop(arg_void);

  writelock(dfaSet->lock, machine_id); 
  DEBUG("Freeing machine %ld\n", machine_id);

  freeSmash(dfaSet->smash, machine_id);
  writeunlock(dfaSet->lock);

  return 0;
}
Example #6
0
static void* worker(void* arg) {
  Page * p = arg;
  for(unsigned long i = 0; i < numops; i++) {
    writelock(p->rwlatch,0);
    stasis_dirty_page_table_set_dirty(dpt, p);
    unlock(p->rwlatch);
  }
  return 0;
}
Example #7
0
RTSPServer::RTSPClientPtr RTSPServer::CreateRTSPClientSession()
{
    srand(unsigned(time(0)));
	RTSPClientPtr clientptr = RTSPClientPtr(new RTSPClientSession(this,
		((unsigned int)((rand()%128) + 1)) * 16777216 + RTSPClientSession::GetStaticFakeClientNUM()));
	writeLock writelock(m_clientListMutex_);
	m_rtspClientList.push_front(clientptr);
	return clientptr;
}
Example #8
0
void *writer (void *args)
{
    rwargs *a = static_cast<rwargs *>(args);

    for (int i = 2; i < MAXCOUNT; ++i)
    {
        writelock (a->lock, a->id);
        data = i;
        usleep (a->delay);
        writeunlock (a->lock);
        RPMS_DEBUG( LOGNAME, "Writer " + rpms::convert<std::string>(a->id) + ": Wrote " + rpms::convert<std::string>(i));
        usleep (a->delay);
    }
    RPMS_DEBUG( LOGNAME, "Writer " + rpms::convert<std::string>(a->id) + ": finishing... " );
    writelock (a->lock, a->id);
    data = 0;
    writeunlock (a->lock);
    RPMS_DEBUG( LOGNAME, "Writer " + rpms::convert<std::string>(a->id) + ": finished" );

    return 0;
}
Example #9
0
static int stasis_log_impl_in_memory_truncate(stasis_log_t * log, lsn_t lsn) {
  stasis_log_impl_in_memory * impl = log->impl;
  writelock(impl->flushedLSN_lock,1);
  writelock(impl->globalOffset_lock,1);

  assert(lsn <= impl->nextAvailableLSN);


  if(lsn > impl->globalOffset) {
    for(int i = impl->globalOffset; i < lsn; i++) {
      free(impl->buffer[i - impl->globalOffset]);
    }
    assert((lsn-impl->globalOffset) + (impl->nextAvailableLSN -lsn) <= impl->bufferLen);
    memmove(&(impl->buffer[0]), &(impl->buffer[lsn - impl->globalOffset]),
			sizeof(LogEntry*) * (impl->nextAvailableLSN - lsn));
    impl->globalOffset = lsn;
  }

  writeunlock(impl->globalOffset_lock);
  writeunlock(impl->flushedLSN_lock);

  return 0;
}
Example #10
0
/*
 * kvs_recno_alloc --
 *	Allocate a new record number.
 */
static INLINE int
kvs_recno_alloc(WT_CURSOR *wt_cursor)
{
	struct kvs_record *r;
	CURSOR *cursor;
	WT_SESSION *session;
	int ret;

	cursor = (CURSOR *)wt_cursor;
	session = cursor->session;
	r = &cursor->record;

	/* Lock the data-source. */
	if ((ret = writelock(session, &cursor->data_source->lock)) != 0)
		return (ret);

	/*
	 * If not yet tracking the maximum record number, read the last record
	 * from the object and figure it out.
	 *
	 * XXX
	 * There is still a race here.  If another thread of control performs a
	 * WT_CURSOR::insert of an explicit record number (that is, the other
	 * cursor isn't configured for "append"), we could race.  If we figure
	 * out the last record in the data-source is 37, then the other thread
	 * explicitly writes record 37, things will go badly.  I don't want to
	 * lock the data-source on every update, so I'm leaving this until we
	 * write the transactional code, because that's going to change all of
	 * the locking in here.
	 */
	if (cursor->data_source->append_recno == 0) {
		if ((ret = kvs_last(cursor->data_source->kvs,
		    &cursor->record, (unsigned long)0, (unsigned long)0)) != 0)
			goto err;

		if ((ret = wt_ext->struct_unpack(wt_ext, session,
		    r->key, sizeof(r->key),
		    "r", &cursor->data_source->append_recno)) != 0)
			goto err;
	}

	wt_cursor->recno = ++cursor->data_source->append_recno;

err:	ETRET(unlock(session, &cursor->data_source->lock));
	return (ret);
}
Example #11
0
recordid TallocFromPage(int xid, pageid_t page, unsigned long size) {
  stasis_alloc_t* alloc = stasis_runtime_alloc_state();
  short type;
  if(size >= BLOB_THRESHOLD_SIZE) {
    type = BLOB_SLOT;
  } else {
    assert(size > 0);
    type = size;
  }

  pthread_mutex_lock(&alloc->mut);
  if(!stasis_allocation_policy_can_xid_alloc_from_page(alloc->allocPolicy, xid, page)) {
    pthread_mutex_unlock(&alloc->mut);
    return NULLRID;
  }
  Page * p = loadPage(xid, page);
  writelock(p->rwlatch,0);
  recordid rid = stasis_record_alloc_begin(xid, p, type);


  if(rid.size != INVALID_SLOT) {
    stasis_record_alloc_done(xid,p,rid);
    stasis_allocation_policy_alloced_from_page(alloc->allocPolicy, xid, page);
    unlock(p->rwlatch);

    alloc_arg a = { rid.slot, type };

    Tupdate(xid, rid.page, &a, sizeof(a), OPERATION_ALLOC);

    if(type == BLOB_SLOT) {
      rid.size = size;
      stasis_blob_alloc(xid,rid);
    }
  } else {
    unlock(p->rwlatch);
  }

  releasePage(p);
  pthread_mutex_unlock(&alloc->mut);

  stasis_transaction_table_set_argument(alloc->xact_table, xid, alloc->callback_id,
					AT_COMMIT, alloc);
  return rid;
}
Example #12
0
/*
 * kvs_session_truncate --
 *	WT_SESSION::truncate method.
 */
static int
kvs_session_truncate(WT_DATA_SOURCE *dsrc,
    WT_SESSION *session, const char *uri, WT_CONFIG_ARG *config)
{
	DATA_SOURCE *p;
	int ret, tret;

	(void)dsrc;				/* Unused parameters */

	/*
	 * Truncate should work even if the object is not yet opened: if we
	 * don't find it, open it.   We loop because we could theoretically
	 * race with other threads creating/deleting the object.
	 */
	for (;;) {
		if ((ret = writelock(session, &global_lock)) != 0)
			return (ret);

		/* Search our list of objects for a match. */
		for (p = data_source_head; p != NULL; p = p->next)
			if (strcmp(p->uri, uri) == 0)
				break;

		/* If we don't find the object, open it. */
		if (p == NULL) {
			if ((ret = unlock(session, &global_lock)) != 0)
				return (ret);
			if ((ret = open_data_source(session, uri, config)) != 0)
				return (ret);
			continue;
		}
		if (p->open_cursors == 0) {
			if ((tret = kvs_truncate(p->kvs)) != 0)
				ESET(NULL, WT_ERROR,
				    "kvs_truncate: %s: %s",
				    p->uri, kvs_strerror(tret));
		} else
			ret = EBUSY;
		ETRET(unlock(session, &global_lock));
		return (ret);
	}
	/* NOTREACHED */
}
Example #13
0
static int
single_thread(
    WT_DATA_SOURCE *wtds, WT_SESSION *session, pthread_rwlock_t *lockp)
{
	DATA_SOURCE *ds;
	WT_EXTENSION_API *wt_api;
	int ret = 0;

	ds = (DATA_SOURCE *)wtds;
	wt_api = ds->wt_api;

	if ((ret = writelock(wt_api, session, lockp)) != 0)
		return (ret);
	if (ds->open_cursors != 0) {
		if ((ret = unlock(wt_api, session, lockp)) != 0)
			return (ret);
		return (EBUSY);
	}
	return (0);
}
Example #14
0
/*
 * kvs_cursor_close --
 *	WT_CURSOR::close method.
 */
static int
kvs_cursor_close(WT_CURSOR *wt_cursor)
{
	CURSOR *cursor;
	WT_SESSION *session;
	int ret;

	cursor = (CURSOR *)wt_cursor;
	session = cursor->session;
	ret = 0;

	if ((ret = writelock(session, &global_lock)) != 0)
		goto err;
	--cursor->data_source->open_cursors;
	if ((ret = unlock(session, &global_lock)) != 0)
		goto err;

err:	free(cursor->val);
	free(cursor);
	return (ret);
}
Example #15
0
/*
 * wiredtiger_extension_terminate --
 *	Shutdown the KVS connector code.
 */
int
wiredtiger_extension_terminate(WT_CONNECTION *connection)
{
	DATA_SOURCE *p;
	int ret, tret;

	(void)connection;			/* Unused parameters */

	ret = writelock(NULL, &global_lock);

	/* Start a flush on any open objects. */
	for (p = data_source_head; p != NULL; p = p->next)
		if ((tret = kvs_commit(p->kvs)) != 0)
			ESET(NULL, WT_ERROR,
			    "kvs_commit: %s: %s", p->uri, kvs_strerror(tret));

	/* Complain if any of the objects are in use. */
	for (p = data_source_head; p != NULL; p = p->next)
		if (p->open_cursors != 0)
			ESET(NULL, WT_ERROR,
			    "%s: has open cursors during close", p->uri);

	/* Close and discard the remaining objects. */
	while ((p = data_source_head) != NULL) {
		if ((tret = kvs_close(p->kvs)) != 0)
			ESET(NULL, WT_ERROR,
			    "kvs_close: %s: %s", p->uri, kvs_strerror(tret));
		data_source_head = p->next;
		free(p->uri);
		ETRET(lock_destroy(NULL, &p->lock));
		free(p);
	}

	ETRET(unlock(NULL, &global_lock));
	ETRET(lock_destroy(NULL, &global_lock));

	wt_ext = NULL;

	return (ret);
}
Example #16
0
int dfa_reinitialize(DfaSet *dfaSet, char * localhost,
	      Transition transitions[], int transition_count, 
	      State states[], state_name state_count) {

  dfaSet->lock = initlock();
  dfaSet->states = states;
  dfaSet->state_count = state_count;
  dfaSet->transitions = transitions;
  dfaSet->transition_count = transition_count;

  if(init_network_broadcast(&(dfaSet->networkSetup), dfaSet->networkSetup.localport, localhost,
			    dfaSet->networkSetup.broadcast_lists,
			    dfaSet->networkSetup.broadcast_lists_count,
			    dfaSet->networkSetup.broadcast_list_host_count) < 0) {
    return -1;
  }
  writelock(dfaSet->lock, 100);
  recover(dfaSet);
  writeunlock(dfaSet->lock);

  return 0;

}
Example #17
0
static int
kvs_cursor_close(WT_CURSOR *wtcursor)
{
	CURSOR_SOURCE *cursor;
	DATA_SOURCE *ds;
	DB *db;
	DBC *dbc;
	WT_EXTENSION_API *wt_api;
	WT_SESSION *session;
	int ret = 0;

	session = wtcursor->session;
	cursor = (CURSOR_SOURCE *)wtcursor;
	ds = cursor->ds;
	wt_api = cursor->wt_api;

	dbc = cursor->dbc;
	cursor->dbc = NULL;
	if (dbc != NULL && (ret = dbc->close(dbc)) != 0)
		ERET(wt_api, session, WT_ERROR,
		    "DbCursor.close: %s", db_strerror(ret));

	db = cursor->db;
	cursor->db = NULL;
	if (db != NULL && (ret = db->close(db, 0)) != 0)
		ERET(wt_api,
		    session, WT_ERROR, "Db.close: %s", db_strerror(ret));
	free(wtcursor);

	if ((ret = writelock(wt_api, session, &ds->rwlock)) != 0)
		return (ret);
	--ds->open_cursors;
	if ((ret = unlock(wt_api, session, &ds->rwlock)) != 0)
		return (ret);

	return (0);
}
Example #18
0
/*
 * drop_data_source --
 *	Drop a data source from our list, closing any underlying KVS handle.
 */
static int
drop_data_source(WT_SESSION *session, const char *uri)
{
	DATA_SOURCE *p, **ref;
	int ret;

	if ((ret = writelock(session, &global_lock)) != 0)
		return (ret);

	/* Search our list of objects for a match. */
	for (ref = &data_source_head; (p = *ref) != NULL; p = p->next)
		if (strcmp(p->uri, uri) == 0)
			break;

	/*
	 * If we don't find the URI in our object list, we're done.
	 * If the object is in use (it has open cursors), we can't drop it.
	 * Otherwise, drop it.
	 */
	if (p == NULL || p->open_cursors != 0) {
		if (p != NULL)
			ret = EBUSY;
	} else {
		if ((ret = kvs_close(p->kvs)) != 0)
			ESET(session, WT_ERROR,
			    "kvs_close: %s: %s", uri, kvs_strerror(ret));
		*ref = p->next;

		free(p->uri);
		ETRET(lock_destroy(session, &p->lock));
		free(p);
	}

	ETRET(unlock(session, &global_lock));
	return (ret);
}
Example #19
0
void
RWMutex::lock()
{
   writelock();
}
Example #20
0
void* main_loop(DfaSet *dfaSet) {

  Message * message = malloc(sizeof(Message));
  char * from = malloc(sizeof(char) * MAX_ADDRESS_LENGTH);
  NetworkSetup * networkSetup = malloc(sizeof(NetworkSetup));
  int recieved_message = 0;

  StateMachine * stateMachine;
  
  writelock(dfaSet->lock, 300);
  memcpy(networkSetup, &(dfaSet->networkSetup), sizeof(NetworkSetup));
  writeunlock(dfaSet->lock);

  /** @todo the locking scheme for this loop could be improved.  The loop assumes that 
	    pointers to existing state machines could be invalidated by unrelated threads, 
            and this forces it to hold a global write lock during processing. */
  
  while(1) {
    int i;
    state_name new_state, current_state;
    int new_machine = 0;

    /*Listen on socket... */
    if(recieved_message) {
      writeunlock(dfaSet->lock); 
      recieved_message = 0;
    }

    if(receive_message(networkSetup, message, from) <= 0) {
      continue;
    }

    recieved_message = 1;
    
    writelock(dfaSet->lock, 200);

    stateMachine = getSmash(dfaSet->smash, message->to_machine_id);
    DEBUG("Lookup %ld, ret = %d\n", message->to_machine_id, ret);

    /** @todo Check states to make sure they actually exist? */
    
    if(stateMachine == NULL) {
    
      DEBUG("Allocate machine %ld->", message->to_machine_id); fflush(NULL); 
      
      if(message->to_machine_id == NULL_MACHINE) {
	
	stateMachine = allocSmash(dfaSet->smash);
	
      } else {
	
	/* @todo: Check id. */	  
	stateMachine = insertSmash(dfaSet->smash, message->to_machine_id);
      }
      
      if(stateMachine == NULL) {
	fprintf(stderr, "Too many state machines.  Dropping request for new one.\n");
	continue;
      }
      
      new_machine = 1;

      stateMachine->worker_thread  = (pid_t)0;
      
      stateMachine->page      = NULL; 
      /* @todo libdfa doesn't use the 'conventional' null recordid, {0,0,-1} */
      stateMachine->page_id.page = 0; 
      stateMachine->page_id.slot = 0;
      stateMachine->page_id.size = 0;  
      
      current_state = NULL_STATE;
    } else {
      current_state = stateMachine->current_state;
    }
    
    new_state = current_state; 
    
    /* Find the appropriate transition */

    assert(message->to_machine_id == stateMachine->machine_id  || message->to_machine_id == NULL_MACHINE);
    
    for(i = 0; i< dfaSet->transition_count; i++) {
      if(dfaSet->transitions[i].remote_state == message->type && 
	 dfaSet->transitions[i].pre_state    == current_state) { 
	
	break;
      }
    }
    
    if(i == dfaSet->transition_count) {
      
      fprintf(stderr, "%ld received: %ld-%d:%d->? (bad message from %s)\n",  stateMachine->machine_id, message->from_machine_id, 
	     message->type, current_state, from);
      continue;
      
    } 
    
    
    if(dfaSet->transitions[i].fcn_ptr == NULL) {
      
      new_state = dfaSet->transitions[i].post_state;
      
    } else {
      
      /* Evaluate callback -- This produces a new state, and
	 overwrites m with a new message for the state machine. */

      int ret = (dfaSet->transitions[i].fcn_ptr)(dfaSet, stateMachine, message, from);
      
      if (dfaSet->transitions[i].post_state == OVERRIDDEN_STATE) {
	if( ret != OVERRIDDEN_STATE) {
	  
	  new_state = ret;
	
	} /* else leave new_state alone; the transition failed. */
      } else if (ret) {
	
 	new_state = dfaSet->transitions[i].post_state;
	
      }
      
    }
    
    
    /* Update machine state. */
    
    if(new_state == NULL_STATE) {
      
      /* Time to de-allocate machine */ 
      
      if(stateMachine->worker_thread == (pid_t)0) {
	
	/* No worker thread, so just deallocate, and move on */

	freeSmash(dfaSet->smash, stateMachine->machine_id);
	continue;

      } else {
	
	/* NULL_STATE_TOMBSTONE tells the worker thread that it's
	   time to shut down.  (NULL_STATE is reserved by monoTree
	   for machines that have already been deleted..) */
	
	new_state = NULL_STATE_TOMBSTONE;
      }
      assert(!new_machine);
    }

    if(new_state != current_state) {
      
      DEBUG("%ld transitioned on: %ld-%d:%d->%d from %s\n", stateMachine->machine_id, message->from_machine_id, 
	     dfaSet->transitions[i].remote_state, dfaSet->transitions[i].pre_state, dfaSet->transitions[i].post_state, from); 
      DEBUG(" -> %d %ld\n", new_state, message->from_machine_id);

      assert(new_state != NULL_STATE);
      stateMachine->current_state = new_state;	
      stateMachine->last_transition = time(NULL);
      
      /* @todo Is this general enough?  The transition function is
	 able to overwrite both variables, so it should be
	 good enough. */
      
      memcpy(&(stateMachine->message_recipient), from, MAX_ADDRESS_LENGTH);
      memcpy(&(stateMachine->message), message, sizeof(Message));
      
      /* We don't want to just swap the sender and recipient,
	 since we might have just allocated this machine.  If not,
	 then the original message's recipient should be the
	 same as stateMachine->machine_id anyway. 
	 
	 At any rate, the transition function should overwrite
	 message->from_machine_id to change the machine that the
	 state machine will deal with.
	 
      */
      
      stateMachine->message.from_machine_id = stateMachine->machine_id;
      stateMachine->message.to_machine_id   = message->from_machine_id;
      
      if(dfaSet->transitions[i].force) {
	setSmash(dfaSet->smash, stateMachine->machine_id);
	forceSmash(dfaSet->smash); 
      }

      /* Fork or signal the process if there already is one. */
      
      if(stateMachine->worker_thread == (pthread_t)NULL) {
 	assert ((stateMachine->current_state != NULL_STATE) && 
 		(stateMachine->current_state != NULL_STATE_TOMBSTONE));

	stateMachine->worker_thread = spawn_worker_thread(dfaSet, stateMachine->machine_id);

      } else {
	// This was a broadcast, but was recently changed to signal for 
	// performance reasons.
	pthread_cond_signal(stateMachine->sleepCond);
      }
    }
  }
}
Example #21
0
// expects single null terminated strings (line ends dont matter)
int getgpsinfo(int chan, char *buf, int msclock)
{
    char *c, *d;
    int i, fmax;

    c = buf;

    d = NULL;
    // required for pathologic cases of $GPABC...$GPXYZ...*ck 
    // where $GPABC... resolves to zero
    for (;;) {                  // find last $ - start of NMEA
        c = strchr(c, '$');
        if (!c)
            break;
        d = c;
        c++;
    }
    if (!d)
        return 0;

    // ignore all but standard NMEA
    if (*d != '$')
        return 0;
    if (d[1] != 'G')
        return 0;
    if (d[2] != 'P' && d[2] != 'N' && d[2] != 'L')
        return 0;

    c = d;
    c++;

    //verify checksum
    i = 0;
    while (*c && *c != '*')
        i ^= *c++;
    if (!*c || (unsigned) (i & 0xff) != strtoul(++c, NULL, 16)) {
        fprintf(errfd, "Bad NMEA Checksum, calc'd %02x:\n %s", i, d);
        return -1;
    }
    --c;
    //null out asterisk
    *c = 0;

    c = d;

    //find and update timestamp
    for (cidx = 0; cidx < MAXSRC; cidx++)
        if (gpst[cidx].gpsfd == chan || gpst[cidx].gpsfd == -2) // found or EOL
            break;
    if (cidx == MAXSRC)         // full, find empty or stale
        for (cidx = 0; cidx < MAXSRC; cidx++)
            if (gpst[cidx].gpsfd < 0 || (100000 + msclock - gpst[cidx].lastseen) % 100000 > 1250)
                break;
    gpst[cidx].gpsfd = chan;
    gpst[cidx].lastseen = msclock;

    //Split into fields at the commas
    fmax = 0;
    c += 2;
    char satype = *c++;         // P,L,N
    for (;;) {
        field[fmax++] = c;
        c = strchr(c, ',');
        if (c == NULL)
            break;
        *c++ = 0;
    }

    //Latitude, Longitude, and other info
    if (fmax == 13 && !strcmp(field[0], "RMC")) {
        //NEED TO VERIFY FMAX FOR EACH
        if (field[2][0] != 'A') {
            if (gpst[cidx].lock)
                gpst[cidx].lock = 0;
            return 1;
        } else {
            if (!gpst[cidx].lock)
                gpst[cidx].lock = 1;
            gethms(1);
            getll(3);
            gpst[cidx].gspd = getndp(field[7], 3) * 1151 / 1000;
            //convert to MPH
            gpst[cidx].gtrk = getndp(field[8], 3);
            //Date, DDMMYY
            gpst[cidx].dy = get2(field[9]);
            gpst[cidx].mo = get2(&field[9][2]);
            gpst[cidx].yr = get2(&field[9][4]);

            // this will be slightly late
            if (!firstlock)
                writelock();
        }
    } else if (fmax == 15 && (!strcmp(field[0], "GGA") || !strcmp(field[0], "GNS"))) {
        i = field[6][0] - '0';
        // was gpst[cidx].lock, but it would prevent GPRMC alt
        if (!i)
            return 1;
        else if (gpst[cidx].lock != i)
            gpst[cidx].lock = i;
        // Redundant: getll(2);
        // don't get this here since it won't increment the YMD
        // and create a midnight bug
        //       gethms(1);
        //7 - 2 plc Sats Used
        // 8 - HDOP
        gpst[cidx].hdop = getndp(field[8], 3);
        gpst[cidx].alt = getndp(field[9], 3);
        //9, 10 - Alt, units M
    }
#if 0                           // depend on RMC to avoid midnight bugs
    else if (fmax == 8 && !strcmp(field[0], "GLL")) {
        if (field[6][0] != 'A') {
#if 0                           // this will cause problems for the kml rotate if the time is wrong
            if (strlen(field[5]))
                gethms(5);
#endif
            if (gpst[cidx].lock)
                gpst[cidx].lock = 0;
            return 1;
        }
        if (!gpst[cidx].lock)
            gpst[cidx].lock = 1;
        getll(1);
        gethms(5);
    }
#endif
#if 0
    else if (fmax == 10 && !strcmp(field[0], "VTG")) {
        gpst[cidx].gtrk = getndp(field[1], 3);
        gpst[cidx].gspd = getndp(field[5], 3) * 1151 / 1000;
        //convert to MPH
    }
#endif
    //Satellites and status
    else if (!(fmax & 3) && fmax >= 8 && fmax <= 20 && !strcmp(field[0], "GSV")) {
        int j, tot, seq;
        //should check (fmax % 4 == 3)
        tot = getndp(field[1], 0);
        seq = getndp(field[2], 0);
        if (satype == 'P') {
            if (seq == 1)
                for (j = 0; j < 65; j++)
                    gpsat[cidx].view[j] = 0;
            gpsat[cidx].pnsats = getndp(field[3], 0);
            gpsat[cidx].psatset &= (1 << tot) - 1;
            gpsat[cidx].psatset &= ~(1 << (seq - 1));
        } else {
            if (seq == 1)
                for (j = 65; j < 100; j++)
                    gpsat[cidx].view[j] = 0;
            gpsat[cidx].lnsats = getndp(field[3], 0);
            gpsat[cidx].lsatset &= (1 << tot) - 1;
            gpsat[cidx].lsatset &= ~(1 << (seq - 1));
        }

        for (j = 4; j < 20 && j < fmax; j += 4) {
            i = getndp(field[j], 0);
            if (!i)
                break;
            if (i > 119)        // WAAS,EGNOS high numbering
                i -= 87;
            if (i > 100)
                i -= 46; //QZSS will be 60..64
            gpsat[cidx].view[i] = 1;
            gpsat[cidx].el[i] = getndp(field[j + 1], 0);
            gpsat[cidx].az[i] = getndp(field[j + 2], 0);
            gpsat[cidx].sn[i] = getndp(field[j + 3], 0);
        }
        int n;
        if (satype == 'P' && !gpsat[cidx].psatset) {
            gpst[cidx].pnsats = 0;
            gpst[cidx].pnused = 0;
            for (n = 0; n < 65; n++) {
                if (gpsat[cidx].view[n]) {
                    int k = gpst[cidx].pnsats++;
                    gpst[cidx].psats[k].num = n;
                    gpst[cidx].psats[k].el = gpsat[cidx].el[n];
                    gpst[cidx].psats[k].az = gpsat[cidx].az[n];
                    gpst[cidx].psats[k].sn = gpsat[cidx].sn[n];
                    if (gpsat[cidx].used[n]) {
                        gpst[cidx].pnused++;
                        gpst[cidx].psats[k].num = -n;
                    } else
                        gpst[cidx].psats[k].num = n;
                }
            }
        }
        // else
        if (satype == 'L' && !gpsat[cidx].lsatset) {
            gpst[cidx].lnsats = 0;
            gpst[cidx].lnused = 0;
            for (n = 65; n < 99; n++) {
                if (gpsat[cidx].view[n]) {
                    int k = gpst[cidx].lnsats++;
                    gpst[cidx].lsats[k].num = n;
                    gpst[cidx].lsats[k].el = gpsat[cidx].el[n];
                    gpst[cidx].lsats[k].az = gpsat[cidx].az[n];
                    gpst[cidx].lsats[k].sn = gpsat[cidx].sn[n];
                    if (gpsat[cidx].used[n]) {
                        gpst[cidx].lnused++;
                        gpst[cidx].lsats[k].num = -n;
                    } else
                        gpst[cidx].lsats[k].num = n;
                }
            }
        }
    } else if (fmax == 18 && !strcmp(field[0], "GSA")) {
        gpst[cidx].fix = getndp(field[2], 0);
        gpst[cidx].pdop = getndp(field[15], 3);
        gpst[cidx].hdop = getndp(field[16], 3);
        gpst[cidx].vdop = getndp(field[17], 3);

        int j = getndp(field[3], 0);
        if (j > 119)
            j -= 87;
        if (j && j < 65) {
            gpsat[cidx].psatset = 255;
            for (i = 0; i < 65; i++)
                gpsat[cidx].used[i] = 0;
            gpsat[cidx].pnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat[cidx].used[k]++;
                    gpsat[cidx].pnused++;
                }
                // else break;?
            }
        }
        if (j && j > 64) {
            gpsat[cidx].lsatset = 255;
            for (i = 65; i < 100; i++)
                gpsat[cidx].used[i] = 0;
            gpsat[cidx].lnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat[cidx].used[k]++;
                    gpsat[cidx].lnused++;
                }
                // else break;?
            }
        }
    }
#if 0
    else
        printf("?%s\n", field[0]);
#endif
    if (bestgps != cidx)
        return 1;

    if (!gpst[cidx].mo || !gpst[cidx].dy)
        return 1;
    // within 24 hours, only when gpst[cidx].lock since two unlocked GPS can have different times
    // only when sc < 30 to avoid bestgps jitter (5:00->4:59) causing a hiccup
    if (firstlock == 1 || (kmlinterval && gpst[cidx].lock && gpst[cidx].sc < 30
        && kmmn != (gpst[cidx].hr * 60 + gpst[cidx].mn) / kmlinterval)) {
        firstlock = 2;
        kmmn = (gpst[cidx].hr * 60 + gpst[cidx].mn) / kmlinterval;
        rotatekml();

        sprintf(currkml, "%02d%02d%02d%02d%02d%02d.kml",
          gpst[cidx].yr, gpst[cidx].mo, gpst[cidx].dy, gpst[cidx].hr, gpst[cidx].mn, gpst[cidx].sc);
        logfd = fopen(currkml, "w+b");
        if (logfd) {
            symlink(currkml, "current.kml");    // this will fail on FAT
            fprintf(logfd, kmlhead, kmlname, gpst[cidx].llon / 1000000, abs(gpst[cidx].llon % 1000000),
              gpst[cidx].llat / 1000000, abs(gpst[cidx].llat % 1000000), gpst[cidx].gtrk / 1000, gpst[cidx].gtrk % 1000);
            fflush(logfd);
        }
    }
    if (kmlsc == gpst[cidx].sc && kmscth == gpst[cidx].scth)
        return 1;
    if (!gpst[cidx].llat && !gpst[cidx].llon)   // time, but no location
        return 1;

    if (kmlsc != gpst[cidx].sc) {
        if (!kmlinterval || !logfd)
            return 1;
        kmlsc = gpst[cidx].sc;
        sprintf(&kmlstr[kmlful], pmarkfmt, gpst[cidx].llon / 1000000, abs(gpst[cidx].llon % 1000000), gpst[cidx].llat / 1000000, abs(gpst[cidx].llat % 1000000), gpst[cidx].gspd / 1000, gpst[cidx].gspd % 1000,        // last point this second, first point next below.
          gpst[cidx].yr, gpst[cidx].mo, gpst[cidx].dy, gpst[cidx].hr, gpst[cidx].mn, gpst[cidx].sc);
        kmlful = strlen(kmlstr);
    }

    kmscth = gpst[cidx].scth;
    sprintf(&kmlstr[kmlful], "%d.%06d,%d.%06d,%d.%03d\n", gpst[cidx].llon / 1000000, abs(gpst[cidx].llon % 1000000),
      gpst[cidx].llat / 1000000, abs(gpst[cidx].llat % 1000000), gpst[cidx].gspd / 1000, gpst[cidx].gspd % 1000);
    kmlful = strlen(kmlstr);

    if (kmlful > BUFLEN / 2)
        dokmltail();
    return 2;
}
Example #22
0
static void paReleasePage(stasis_buffer_manager_t *bm, Page * p) {
  writelock(p->rwlatch,0);
  stasis_dirty_page_table_set_clean(stasis_runtime_dirty_page_table(), p);
  unlock(p->rwlatch);
}
Example #23
0
/*
 * open_data_source --
 *	Open a new data source and insert it into the list.
 */
static int
open_data_source(WT_SESSION *session, const char *uri, WT_CONFIG_ARG *config)
{
	struct kvs_config kvs_config;
	DATA_SOURCE *data_source, *p;
	int ds_lockinit, flags, locked, ret;
	char **devices, *emsg;

	devices = NULL;
	emsg = NULL;
	ds_lockinit = locked = ret = 0;

	/*
	 * The first time we open a cursor on an object, allocate an underlying
	 * data source object.
	 */
	if ((data_source =
	    (DATA_SOURCE *)calloc(1, sizeof(DATA_SOURCE))) == NULL)
		return (os_errno());
	if ((data_source->uri = strdup(uri)) == NULL)
		goto err;
	if ((ret = lock_init(session, &data_source->lock)) != 0)
		goto err;
	ds_lockinit = 1;

	/* Read the configuration. */
	if ((ret = kvs_config_read(
	    session, config, &devices, &kvs_config, &flags)) != 0)
		goto err;

	/* We require a list of devices underlying the URI. */
	if (devices[0] == NULL) {
		ESET(
		    session, EINVAL, "WT_SESSION.create: no devices specified");
		goto err;
	}

	/*
	 * kvs_open isn't re-entrant: lock things down while we make sure we
	 * don't have more than a single handle at a time.
	 */
	if ((ret = writelock(session, &global_lock)) != 0)
		goto err;
	locked = 1;

	/*
	 * Check for a match: if we find one, we raced, but we return success,
	 * someone else did the work.
	 */
	for (p = data_source_head; p != NULL; p = p->next)
		if (strcmp(p->uri, uri) == 0)
			goto err;

	/* Open the KVS handle. */
	if ((data_source->kvs =
	    kvs_open(devices, &kvs_config, flags)) == NULL) {
		emsg = kvs_create_path_string(devices);
		ESET(session, WT_ERROR,
		    "WT_SESSION.create: kvs_open: %s: %s",
		    emsg == NULL ? devices[0] : emsg, kvs_strerror(os_errno()));
		goto err;
	}

	/* Insert the new entry at the head of the list. */
	data_source->next = data_source_head;
	data_source_head = data_source;
	data_source = NULL;

err:	if (locked)
		ETRET(unlock(session, &global_lock));

	if (data_source != NULL) {
		if (data_source->uri != NULL)
			free(data_source->uri);
		if (ds_lockinit)
			ETRET(lock_destroy(session, &data_source->lock));
		free(data_source);
	}
	free(devices);
	free(emsg);
	return (ret);
}
Example #24
0
recordid Talloc(int xid, unsigned long size) {
  stasis_alloc_t* alloc = stasis_runtime_alloc_state();
  short type;
  if(size >= BLOB_THRESHOLD_SIZE) {
    type = BLOB_SLOT;
  } else {
    assert(size >= 0);
    type = size;
  }

  recordid rid;

  pthread_mutex_lock(&alloc->mut);

  pageid_t pageid =
      stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid,
                               stasis_record_type_to_size(type));

  if(pageid == INVALID_PAGE) {
    stasis_alloc_reserve_new_region(alloc, xid);
    pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid,
                                    stasis_record_type_to_size(type));
  }
  alloc->lastFreepage = pageid;

  Page * p = loadPage(xid, alloc->lastFreepage);

  writelock(p->rwlatch, 0);
  int rec_size = stasis_record_type_to_size(type);
  if(rec_size < 4) { rec_size = 4; }
  while(stasis_record_freespace(xid, p) < rec_size) {
    stasis_record_compact(p);
    int newFreespace = stasis_record_freespace(xid, p);

    if(newFreespace >= rec_size) {
      break;
    }

    unlock(p->rwlatch);
    stasis_allocation_policy_update_freespace(alloc->allocPolicy, pageid, newFreespace);
    releasePage(p);

    pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid,
                                    rec_size);

    if(pageid == INVALID_PAGE) {
      stasis_alloc_reserve_new_region(alloc, xid);
      pageid = stasis_allocation_policy_pick_suitable_page(alloc->allocPolicy, xid,
                                                       rec_size);
    }

    alloc->lastFreepage = pageid;

    p = loadPage(xid, alloc->lastFreepage);
    writelock(p->rwlatch, 0);
  }

  rid = stasis_record_alloc_begin(xid, p, type);

  assert(rid.size != INVALID_SLOT);

  stasis_record_alloc_done(xid, p, rid);
  int newFreespace = stasis_record_freespace(xid, p);
  stasis_allocation_policy_alloced_from_page(alloc->allocPolicy, xid, pageid);
  stasis_allocation_policy_update_freespace(alloc->allocPolicy, pageid, newFreespace);
  unlock(p->rwlatch);

  alloc_arg a = { rid.slot, type };

  Tupdate(xid, rid.page, &a, sizeof(a), OPERATION_ALLOC);

  if(type == BLOB_SLOT) {
    rid.size = size;
    stasis_blob_alloc(xid, rid);
  }

  releasePage(p);
  pthread_mutex_unlock(&alloc->mut);

  stasis_transaction_table_set_argument(alloc->xact_table, xid, alloc->callback_id,
					AT_COMMIT, alloc);

  return rid;  // TODO return NULLRID on error
}
Example #25
0
static int
kvs_session_open_cursor(WT_DATA_SOURCE *wtds, WT_SESSION *session,
    const char *uri, WT_CONFIG_ARG *config, WT_CURSOR **new_cursor)
{
	CURSOR_SOURCE *cursor;
	DATA_SOURCE *ds;
	DB *db;
	WT_CONFIG_ITEM v;
	WT_EXTENSION_API *wt_api;
	int locked, ret;
	const char *name;

	ds = (DATA_SOURCE *)wtds;
	wt_api = ds->wt_api;
	locked = 0;
						/* Get the object name */
	if ((ret = uri2name(wt_api, session, uri, &name)) != 0)
		return (ret);
						/* Allocate the cursor */
	if ((cursor = calloc(1, sizeof(CURSOR_SOURCE))) == NULL)
		return (os_errno());
	cursor->ds = (DATA_SOURCE *)wtds;
	cursor->wt_api = wt_api;
						/* Parse configuration */
	if ((ret = wt_api->config_get(
	    wt_api, session, config, "append", &v)) != 0) {
		ESET(wt_api, session, ret,
		    "append configuration: %s",
		    wt_api->strerror(wt_api, session, ret));
		goto err;
	}
	cursor->config_append = v.val != 0;

	if ((ret = wt_api->config_get(
	    wt_api, session, config, "overwrite", &v)) != 0) {
		ESET(wt_api, session, ret,
		    "overwrite configuration: %s",
		    wt_api->strerror(wt_api, session, ret));
		goto err;
	}
	cursor->config_overwrite = v.val != 0;

	if ((ret = wt_api->config_get(
	    wt_api, session, config, "key_format", &v)) != 0) {
		ESET(wt_api, session, ret,
		    "key_format configuration: %s",
		    wt_api->strerror(wt_api, session, ret));
		goto err;
	}
	cursor->config_recno = v.len == 1 && v.str[0] == 'r';

	if ((ret = wt_api->config_get(
	    wt_api, session, config, "value_format", &v)) != 0) {
		ESET(wt_api, session, ret,
		    "value_format configuration: %s",
		    wt_api->strerror(wt_api, session, ret));
		goto err;
	}
	cursor->config_bitfield =
	    v.len == 2 && isdigit((u_char)v.str[0]) && v.str[1] == 't';

	if ((ret = writelock(wt_api, session, &ds->rwlock)) != 0)
		goto err;
	locked = 1;
				/* Open the Berkeley DB cursor */
	if ((ret = db_create(&cursor->db, ds->dbenv, 0)) != 0) {
		ESET(wt_api,
		    session, WT_ERROR, "db_create: %s", db_strerror(ret));
		goto err;
	}
	db = cursor->db;
	if ((ret = db->open(db, NULL, name, NULL,
	    cursor->config_recno ? DB_RECNO : DB_BTREE, DB_CREATE, 0)) != 0) {
		ESET(wt_api,
		    session, WT_ERROR, "Db.open: %s", db_strerror(ret));
		goto err;
	}
	if ((ret = db->cursor(db, NULL, &cursor->dbc, 0)) != 0) {
		ESET(wt_api,
		    session, WT_ERROR, "Db.cursor: %s", db_strerror(ret));
		goto err;
	}

				/* Initialize the methods */
	cursor->wtcursor.next = kvs_cursor_next;
	cursor->wtcursor.prev = kvs_cursor_prev;
	cursor->wtcursor.reset = kvs_cursor_reset;
	cursor->wtcursor.search = kvs_cursor_search;
	cursor->wtcursor.search_near = kvs_cursor_search_near;
	cursor->wtcursor.insert = kvs_cursor_insert;
	cursor->wtcursor.update = kvs_cursor_update;
	cursor->wtcursor.remove = kvs_cursor_remove;
	cursor->wtcursor.close = kvs_cursor_close;

	*new_cursor = (WT_CURSOR *)cursor;

	++ds->open_cursors;

	if (0) {
err:		free(cursor);
	}

	if (locked)
		ETRET(unlock(wt_api, session, &ds->rwlock));
	return (ret);
}
Example #26
0
// expects single null terminated strings (line ends dont matter)
int getgpsinfo(char *buf)
{
    char *c, *d;
    int i, fmax;
    c = buf;
    d = NULL;
    // required for pathologic cases of $GPABC...$GPXYZ...*ck
    // where $GPABC... resolves to zero
    for (;;) {                  // find last $ - start of NMEA
        c = strchr(c, '$');
        if (!c)
            break;
        d = c;
        c++;
    }
    if (!d)
        return 0;
    // ignore all but standard NMEA
    if (*d != '$')
        return 0;
    if (d[1] != 'G')
        return 0;
    if (d[2] != 'P' && d[2] != 'N' && d[2] != 'L')
        return 0;
    c = d;
    c++;
    //verify checksum
    i = 0;
    while (*c && *c != '*')
        i ^= *c++;
    if (!*c || (unsigned) (i & 0xff) != strtoul(++c, NULL, 16)) {
        printf("Bad NMEA Checksum, calc'd %02x:\n %s", i, d);
        return -1;
    }
    --c;
    //null out asterisk
    *c = 0;
    c = d;
    //Split into fields at the commas
    fmax = 0;
    c += 2;
    char satype = *c++;         // P,L,N
    for (;;) {
        field[fmax++] = c;
        c = strchr(c, ',');
        if (c == NULL)
            break;
        *c++ = 0;
    }
    //Latitude, Longitude, and other info
    if (fmax == 13 && !strcmp(field[0], "RMC")) {
        //NEED TO VERIFY FMAX FOR EACH
        if (field[2][0] != 'A') {
            if (gpst.lock)
                gpst.lock = 0;
            return 1;
        }
        else {
            if (!gpst.lock)
                gpst.lock = 1;
            gethms(1);
            getll(3);
            gpst.gspd = getndp(field[7], 3) * 1151 / 1000;
            //convert to MPH
            gpst.gtrk = getndp(field[8], 3);
            //Date, DDMMYY
            gpst.dy = get2(field[9]);
            gpst.mo = get2(&field[9][2]);
            gpst.yr = get2(&field[9][4]);
            // this will be slightly late
            if (!firstlock)
                writelock();
        }
    }
    else if (fmax == 15 && (!strcmp(field[0], "GGA") || !strcmp(field[0], "GNS"))) {
        i = field[6][0] - '0';
        // was gpst.lock, but it would prevent GPRMC alt
        if (!i)
            return 1;
        else if (gpst.lock != i)
            gpst.lock = i;
        // Redundant: getll(2);
        // don't get this here since it won't increment the YMD
        // and create a midnight bug
        //       gethms(1);
        //7 - 2 plc Sats Used
        // 8 - HDOP
        gpst.hdop = getndp(field[8], 3);
        gpst.alt = getndp(field[9], 3);
        //9, 10 - Alt, units M
    }
    else if (fmax == 8 && !strcmp(field[0], "GLL")) {
        if (field[6][0] != 'A') {
            if (strlen(field[5]))
                gethms(5);
            if (gpst.lock)
                gpst.lock = 0;
            return 1;
        }
        if (!gpst.lock)
            gpst.lock = 1;
        getll(1);
        gethms(5);
    }
    else if (fmax == 10 && !strcmp(field[0], "VTG")) {
        gpst.gtrk = getndp(field[1], 3);
        gpst.gspd = getndp(field[5], 3) * 1151 / 1000;
        //convert to MPH
    }
    //Satellites and status
    else if (!(fmax & 3) && fmax >= 8 && fmax <= 20 && !strcmp(field[0], "GSV")) {
        int j, tot, seq;
        //should check (fmax % 4 == 3)
        tot = getndp(field[1], 0);
        seq = getndp(field[2], 0);
        if (satype == 'P') {
            if (seq == 1)
                for (j = 0; j < 65; j++)
                    gpsat.view[j] = 0;
            gpsat.pnsats = getndp(field[3], 0);
            gpsat.psatset &= (1 << tot) - 1;
            gpsat.psatset &= ~(1 << (seq - 1));
        }
        else {
            if (seq == 1)
                for (j = 65; j < 100; j++)
                    gpsat.view[j] = 0;
            gpsat.lnsats = getndp(field[3], 0);
            gpsat.lsatset &= (1 << tot) - 1;
            gpsat.lsatset &= ~(1 << (seq - 1));
        }
        for (j = 4; j < 20 && j < fmax; j += 4) {
            i = getndp(field[j], 0);
            if (!i)
                break;
            if (i > 119)        // WAAS,EGNOS high numbering
                i -= 87;
            gpsat.view[i] = 1;
            gpsat.el[i] = getndp(field[j + 1], 0);
            gpsat.az[i] = getndp(field[j + 2], 0);
            gpsat.sn[i] = getndp(field[j + 3], 0);
        }
        int n;
        if (satype == 'P' && !gpsat.psatset) {
            gpst.pnsats = 0;
            gpst.pnused = 0;
            for (n = 0; n < 65; n++) {
                if (gpsat.view[n]) {
                    int k = gpst.pnsats++;
                    gpst.psats[k].num = n;
                    gpst.psats[k].el = gpsat.el[n];
                    gpst.psats[k].az = gpsat.az[n];
                    gpst.psats[k].sn = gpsat.sn[n];
                    if (gpsat.used[n]) {
                        gpst.pnused++;
                        gpst.psats[k].num = -n;
                    }
                    else
                        gpst.psats[k].num = n;
                }
            }
        }
        // else
        if (satype == 'L' && !gpsat.lsatset) {
            gpst.lnsats = 0;
            gpst.lnused = 0;
            for (n = 65; n < 99; n++) {
                if (gpsat.view[n]) {
                    int k = gpst.lnsats++;
                    gpst.lsats[k].num = n;
                    gpst.lsats[k].el = gpsat.el[n];
                    gpst.lsats[k].az = gpsat.az[n];
                    gpst.lsats[k].sn = gpsat.sn[n];
                    if (gpsat.used[n]) {
                        gpst.lnused++;
                        gpst.lsats[k].num = -n;
                    }
                    else
                        gpst.lsats[k].num = n;
                }
            }
        }
    }
    else if (fmax == 18 && !strcmp(field[0], "GSA")) {
        gpst.fix = getndp(field[2], 0);
        gpst.pdop = getndp(field[15], 3);
        gpst.hdop = getndp(field[16], 3);
        gpst.vdop = getndp(field[17], 3);
        int j = getndp(field[3], 0);
        if (j > 119)
            j -= 87;
        if (j && j < 65) {
            gpsat.psatset = 255;
            for (i = 0; i < 65; i++)
                gpsat.used[i] = 0;
            gpsat.pnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat.used[k]++;
                    gpsat.pnused++;
                }
                // else break;?
            }
        }
        if (j && j > 64) {
            gpsat.lsatset = 255;
            for (i = 65; i < 100; i++)
                gpsat.used[i] = 0;
            gpsat.lnused = 0;
            for (i = 3; i < 15; i++) {
                int k = getndp(field[i], 0);
                if (k > 119)
                    k -= 87;
                if (k) {
                    gpsat.used[k]++;
                    gpsat.lnused++;
                }
                // else break;?
            }
        }
    }
    else
        printf("?%s\n", field[0]);
    return -1;
}
Example #27
0
/*
 * kvs_session_open_cursor --
 *	WT_SESSION::open_cursor method.
 */
static int
kvs_session_open_cursor(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
    const char *uri, WT_CONFIG_ARG *config, WT_CURSOR **new_cursor)
{
	CURSOR *cursor;
	DATA_SOURCE *p;
	WT_CONFIG_ITEM v;
	int ret;

	(void)dsrc;				/* Unused parameters */

	cursor = NULL;
	ret = 0;

	/* Allocate and initialize a cursor. */
	if ((cursor = (CURSOR *)calloc(1, sizeof(CURSOR))) == NULL)
		return (os_errno());

	cursor->session = session;
	cursor->record.key = cursor->key;
	if ((cursor->val = malloc(128)) == NULL)
		goto err;
	cursor->val_len = 128;
						/* Initialize the methods */
	cursor->wt_cursor.next = kvs_cursor_next;
	cursor->wt_cursor.prev = kvs_cursor_prev;
	cursor->wt_cursor.reset = kvs_cursor_reset;
	cursor->wt_cursor.search = kvs_cursor_search;
	cursor->wt_cursor.search_near = kvs_cursor_search_near;
	cursor->wt_cursor.insert = kvs_cursor_insert;
	cursor->wt_cursor.update = kvs_cursor_update;
	cursor->wt_cursor.remove = kvs_cursor_remove;
	cursor->wt_cursor.close = kvs_cursor_close;

						/* Parse configuration */
	if ((ret = wt_ext->config_get(
	    wt_ext, session, config, "append", &v)) != 0) {
		ESET(session, ret,
		    "append configuration: %s", wt_ext->strerror(ret));
		goto err;
	}
	cursor->config_append = v.val != 0;

	if ((ret = wt_ext->config_get(
	    wt_ext, session, config, "overwrite", &v)) != 0) {
		ESET(session, ret,
		    "overwrite configuration: %s", wt_ext->strerror(ret));
		goto err;
	}
	cursor->config_overwrite = v.val != 0;

	if ((ret = wt_ext->config_get(
	    wt_ext, session, config, "key_format", &v)) != 0) {
		ESET(session, ret,
		    "key_format configuration: %s", wt_ext->strerror(ret));
		goto err;
	}
	cursor->config_recno = v.len == 1 && v.str[0] == 'r';

	if ((ret = wt_ext->config_get(
	    wt_ext, session, config, "value_format", &v)) != 0) {
		ESET(session, ret,
		    "value_format configuration: %s", wt_ext->strerror(ret));
		goto err;
	}
	cursor->config_bitfield =
	    v.len == 2 && isdigit(v.str[0]) && v.str[1] == 't';

	/*
	 * See if the object already exists: if it does, increment the count of
	 * open cursors to pin it, and release the lock.
	 */
	for (;;) {
		if ((ret = writelock(session, &global_lock)) != 0)
			goto err;
		for (p = data_source_head; p != NULL; p = p->next)
			if (strcmp(p->uri, uri) == 0) {
				++p->open_cursors;
				break;
			}
		if ((ret = unlock(session, &global_lock)) != 0)
			goto err;
		if (p != NULL) {
			cursor->data_source = p;

			*new_cursor = (WT_CURSOR *)cursor;
			return (0);
		}

		/* Create the object. */
		if ((ret = open_data_source(session, uri, config)) != 0)
			goto err;

		/*
		 * We shouldn't loop more than once, but it's theoretically
		 * possible.
		 */
	}

err:	if (cursor != NULL) {
		if (cursor->val != NULL)
			free(cursor->val);
		free(cursor);
	}
	return (ret);
}