예제 #1
0
/*
** Usage: client_swap ID ID
**
** Interchange the sqlite* pointer between two threads.
*/
static int tcl_client_swap(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i, j;
  sqlite3 *temp;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID1 ID2", 0);
    return TCL_ERROR;
  }
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  j = parse_client_id(interp, argv[2]);
  if( j<0 ) return TCL_ERROR;
  if( !threadset[j].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[j]);
  temp = threadset[i].db;
  threadset[i].db = threadset[j].db;
  threadset[j].db = temp;
  return TCL_OK;
}
예제 #2
0
/*
** Usage: client_reset ID
**
** Finalize the virtual machine.
*/
static int tcl_client_reset(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " IDL", 0);
    return TCL_ERROR;
  }
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  threadset[i].xOp = do_reset;
  sqlite3_free(threadset[i].zArg);
  threadset[i].zArg = 0;
  threadset[i].opnum++;
  return TCL_OK;
}
예제 #3
0
/*
** Usage: client_colname  ID   N
**
** Wait on the most recent client_step to complete, then return the
** name of the N-th columns in the result set.
*/
static int tcl_client_colname(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;
  int n;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID N", 0);
    return TCL_ERROR;
  }
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
  client_wait(&threadset[i]);
  if( n<0 || n>=threadset[i].argc ){
    Tcl_AppendResult(interp, "column number out of range", 0);
    return TCL_ERROR;
  }
  Tcl_AppendResult(interp, threadset[i].colv[n], 0);
  return TCL_OK;
}
예제 #4
0
/*
** Usage: client_argc  ID
**
** Wait on the most recent client_step to complete, then return the
** number of columns in the result set.
*/
static int tcl_client_argc(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;
  char zBuf[100];

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID", 0);
    return TCL_ERROR;
  }
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  sprintf(zBuf, "%d", threadset[i].argc);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}
예제 #5
0
/* setup client id from database, otherwise intialize from source */
char *get_client_id(sqlite3 *database, pSource source) {
	char *json_string;
	char url_string[4096];
	char *c_id = NULL;
	prepare_db_statement("SELECT client_id from client_info limit 1",
						 database,
						 &client_id_statement);
	sqlite3_step(client_id_statement);
	c_id = str_assign((char *)sqlite3_column_text(client_id_statement, 0));
	if (c_id != NULL) {
		printf("Using client_id %s from database...\n", c_id);
	} else {
		sqlite3_reset(client_id_statement);
		sprintf(url_string, "%s/clientcreate%s", source->_source_url, SYNC_SOURCE_FORMAT);
		json_string = fetch_remote_data(url_string);
		if(json_string && strlen(json_string) > 0) {
			c_id = str_assign((char *)parse_client_id(json_string));
		}
		prepare_db_statement("INSERT INTO client_info (client_id) values (?)",
							 database,
							 &client_id_statement);
		sqlite3_bind_text(client_id_statement, 1, c_id, -1, SQLITE_TRANSIENT);
		sqlite3_step(client_id_statement);
		printf("Intialized new client_id %s from source...\n", c_id);
	}
	sqlite3_reset(client_id_statement);
	return c_id;
}
예제 #6
0
/*
** Usage: client_result  ID
**
** Wait on the most recent operation to complete, then return the
** result code from that operation.
*/
static int tcl_client_result(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;
  const char *zName;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID", 0);
    return TCL_ERROR;
  }
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( !threadset[i].busy ){
    Tcl_AppendResult(interp, "no such thread", 0);
    return TCL_ERROR;
  }
  client_wait(&threadset[i]);
  switch( threadset[i].rc ){
    case SQLITE_OK:         zName = "SQLITE_OK";          break;
    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
    case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
    default:                zName = "SQLITE_Unknown";     break;
  }
  Tcl_AppendResult(interp, zName, 0);
  return TCL_OK;
}
예제 #7
0
파일: test7.c 프로젝트: 1018824313/sqlite
/*
** Usage:  client_halt ID
**
** Cause a client thread to shut itself down.  Wait for the shutdown to be
** completed.  If ID is "*" then stop all client threads.
*/
static int tcl_client_halt(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID", 0);
    return TCL_ERROR;
  }
  if( argv[1][0]=='*' && argv[1][1]==0 ){
    for(i=0; i<N_THREAD; i++){
      if( threadset[i].busy ){
        stop_thread(&threadset[i]);
      }
    }
  }else{
    i = parse_client_id(interp, argv[1]);
    if( i<0 ) return TCL_ERROR;
    if( !threadset[i].busy ){
      Tcl_AppendResult(interp, "no such thread", 0);
      return TCL_ERROR;
    }
    stop_thread(&threadset[i]);
  }

  /* If no client threads are still running, also stop the server */
  for(i=0; i<N_THREAD && threadset[i].busy==0; i++){}
  if( i>=N_THREAD ){
    sqlite3_server_stop();
    while( 1 ){
      for(i=0; i<N_THREAD && threadset[i].nServer==0; i++);
      if( i==N_THREAD ) break;
      sched_yield();
    }
  }
  return TCL_OK;
}
예제 #8
0
파일: test7.c 프로젝트: 1018824313/sqlite
/*
** Usage:    client_create NAME  FILENAME
**
** NAME should be an upper case letter.  Start the thread running with
** an open connection to the given database.
*/
static int tcl_client_create(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  int i;
  pthread_t x;
  int rc;

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID FILENAME", 0);
    return TCL_ERROR;
  }
  i = parse_client_id(interp, argv[1]);
  if( i<0 ) return TCL_ERROR;
  if( threadset[i].busy ){
    Tcl_AppendResult(interp, "thread ", argv[1], " is already running", 0);
    return TCL_ERROR;
  }
  threadset[i].busy = 1;
  sqlite3_free(threadset[i].zFilename);
  threadset[i].zFilename = sqlite3_mprintf("%s", argv[2]);
  threadset[i].opnum = 1;
  threadset[i].completed = 0;
  rc = pthread_create(&x, 0, client_main, &threadset[i]);
  if( rc ){
    Tcl_AppendResult(interp, "failed to create the thread", 0);
    sqlite3_free(threadset[i].zFilename);
    threadset[i].busy = 0;
    return TCL_ERROR;
  }
  pthread_detach(x);
  if( threadset[i].nServer==0 ){
    threadset[i].nServer = 1;
    sqlite3_server_start2(&threadset[i].nServer);
  }
  return TCL_OK;
}
예제 #9
0
파일: registry.c 프로젝트: maandree/mds
/**
 * Handle the received message containing a ‘Client closed’-header
 * 
 * @return  Zero on success -1 on error or interruption,
 *          `errno` will be set accordingly
 */
static int
handle_close_message(void)
{
	/* Servers do not close too often, there is no need to
	   optimise this with another hash table. Doing so would
	   also require some caution because the keys are 32-bit
	   on 32-bit computers, and the client ID:s are 64-bit. */

	size_t i, j, ptr = 0, size = 1;
	size_t *keys = NULL;
	size_t *old_keys;
	uint64_t client;
	hash_entry_t *entry;
	client_list_t *list;
	char *command;

	/* Remove server for all protocols. */
	for (i = 0; i < received.header_count; i++) {
		if (startswith(received.headers[i], "Client closed: ")) {
			client = parse_client_id(received.headers[i] + strlen("Client closed: "));

			foreach_hash_table_entry (reg_table, j, entry) {
				/* Remove server from list of servers that support the protocol,
				   once, if it is in the list. */
				list = (void *)(entry->value);
				client_list_remove(list, client);
				if (list->size)
					continue;

				/* If no servers support the protocol, list the protocol for removal. */
				fail_if (!keys && xmalloc(keys, size, size_t));
				fail_if (ptr == size ? growalloc(old_keys, keys, size, size_t) : 0);
				keys[ptr++] = entry->key;
			}

	
			/* Mark client as closed. */
			close_slaves(client);
		}