示例#1
0
文件: data.c 项目: amohtasham/rstm
/* =============================================================================
 * data_generate
 * -- Binary variables of random PDFs
 * -- If seed is <0, do not reseed
 * -- Returns random network
 * =============================================================================
 */
net_t*
data_generate (data_t* dataPtr, long seed, long maxNumParent, long percentParent)
{
    random_t* randomPtr = dataPtr->randomPtr;
    if (seed >= 0) {
        random_seed(randomPtr, seed);
    }

    /*
     * Generate random Bayesian network
     */

    long numVar = dataPtr->numVar;
    net_t* netPtr = net_alloc(numVar);
    assert(netPtr);
    net_generateRandomEdges(netPtr, maxNumParent, percentParent, randomPtr);

    /*
     * Create a threshold for each of the possible permutation of variable
     * value instances
     */

    long** thresholdsTable = (long**)SEQ_MALLOC(numVar * sizeof(long*));
    assert(thresholdsTable);
    long v;
    for (v = 0; v < numVar; v++) {
        list_t* parentIdListPtr = net_getParentIdListPtr(netPtr, v);
        long numThreshold = 1 << list_getSize(parentIdListPtr);
        long* thresholds = (long*)SEQ_MALLOC(numThreshold * sizeof(long));
        assert(thresholds);
        long t;
        for (t = 0; t < numThreshold; t++) {
            long threshold = random_generate(randomPtr) % (DATA_PRECISION + 1);
            thresholds[t] = threshold;
        }
        thresholdsTable[v] = thresholds;
    }

    /*
     * Create variable dependency ordering for record generation
     */

    long* order = (long*)SEQ_MALLOC(numVar * sizeof(long));
    assert(order);
    long numOrder = 0;

    queue_t* workQueuePtr = queue_alloc(-1);
    assert(workQueuePtr);

    vector_t* dependencyVectorPtr = vector_alloc(1);
    assert(dependencyVectorPtr);

    bitmap_t* orderedBitmapPtr = bitmap_alloc(numVar);
    assert(orderedBitmapPtr);
    bitmap_clearAll(orderedBitmapPtr);

    bitmap_t* doneBitmapPtr = bitmap_alloc(numVar);
    assert(doneBitmapPtr);
    bitmap_clearAll(doneBitmapPtr);
    v = -1;
    while ((v = bitmap_findClear(doneBitmapPtr, (v + 1))) >= 0) {
        list_t* childIdListPtr = net_getChildIdListPtr(netPtr, v);
        long numChild = list_getSize(childIdListPtr);
        if (numChild == 0) {

            bool_t status;

            /*
             * Use breadth-first search to find net connected to this leaf
             */

            queue_clear(workQueuePtr);
            status = queue_push(workQueuePtr, (void*)v);
            assert(status);
            while (!queue_isEmpty(workQueuePtr)) {
                long id = (long)queue_pop(workQueuePtr);
                status = bitmap_set(doneBitmapPtr, id);
                assert(status);
                status = vector_pushBack(dependencyVectorPtr, (void*)id);
                assert(status);
                list_t* parentIdListPtr = net_getParentIdListPtr(netPtr, id);
                list_iter_t it;
                list_iter_reset(&it, parentIdListPtr);
                while (list_iter_hasNext(&it, parentIdListPtr)) {
                    long parentId = (long)list_iter_next(&it, parentIdListPtr);
                    status = queue_push(workQueuePtr, (void*)parentId);
                    assert(status);
                }
            }

            /*
             * Create ordering
             */

            long i;
            long n = vector_getSize(dependencyVectorPtr);
            for (i = 0; i < n; i++) {
                long id = (long)vector_popBack(dependencyVectorPtr);
                if (!bitmap_isSet(orderedBitmapPtr, id)) {
                    bitmap_set(orderedBitmapPtr, id);
                    order[numOrder++] = id;
                }
            }

        }
    }
    assert(numOrder == numVar);

    /*
     * Create records
     */

    char* record = dataPtr->records;
    long r;
    long numRecord = dataPtr->numRecord;
    for (r = 0; r < numRecord; r++) {
        long o;
        for (o = 0; o < numOrder; o++) {
            long v = order[o];
            list_t* parentIdListPtr = net_getParentIdListPtr(netPtr, v);
            long index = 0;
            list_iter_t it;
            list_iter_reset(&it, parentIdListPtr);
            while (list_iter_hasNext(&it, parentIdListPtr)) {
                long parentId = (long)list_iter_next(&it, parentIdListPtr);
                long value = record[parentId];
                assert(value != DATA_INIT);
                index = (index << 1) + value;
            }
            long rnd = random_generate(randomPtr) % DATA_PRECISION;
            long threshold = thresholdsTable[v][index];
            record[v] = ((rnd < threshold) ? 1 : 0);
        }
        record += numVar;
        assert(record <= (dataPtr->records + numRecord * numVar));
    }

    /*
     * Clean up
     */

    bitmap_free(doneBitmapPtr);
    bitmap_free(orderedBitmapPtr);
    vector_free(dependencyVectorPtr);
    queue_free(workQueuePtr);
    SEQ_FREE(order);
    for (v = 0; v < numVar; v++) {
        SEQ_FREE(thresholdsTable[v]);
    }
    SEQ_FREE(thresholdsTable);

    return netPtr;
}
示例#2
0
int
main(int argc, char **argv)
{
  Pool *pool;
  Queue job;
  Queue solq;
  Solver *solv;
  char *result = 0;
  int resultflags = 0;
  int debuglevel = 0;
  int writeresult = 0;
  int multijob = 0;
  int rescallback = 0;
  int c;
  int ex = 0;
  const char *list = 0;
  FILE *fp;
  const char *p;

  queue_init(&solq);
  while ((c = getopt(argc, argv, "vmrhl:s:")) >= 0)
    {
      switch (c)
      {
        case 'v':
          debuglevel++;
          break;
        case 'r':
          writeresult++;
          break;
        case 'm':
          rescallback = 1;
          break;
        case 'h':
	  usage(0);
          break;
        case 'l':
	  list = optarg;
          break;
        case 's':
	  if ((p = strchr(optarg, ':')))
	    queue_push2(&solq, atoi(optarg), atoi(p + 1));
	  else
	    queue_push2(&solq, 1, atoi(optarg));
          break;
        default:
	  usage(1);
          break;
      }
    }
  if (optind == argc)
    usage(1);
  for (; optind < argc; optind++)
    {
      pool = pool_create();
      pool_setdebuglevel(pool, debuglevel);

      fp = fopen(argv[optind], "r");
      if (!fp)
	{
	  perror(argv[optind]);
	  exit(0);
	}
      while (!feof(fp))
	{
	  queue_init(&job);
	  result = 0;
	  resultflags = 0;
	  solv = testcase_read(pool, fp, argv[optind], &job, &result, &resultflags);
	  if (!solv)
	    {
	      pool_free(pool);
	      exit(1);
	    }

	  if (!multijob && !feof(fp))
	    multijob = 1;

	  if (multijob)
	    printf("test %d:\n", multijob++);
	  if (list)
	    {
	      int selflags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT;
	      if (*list == '/')
		selflags |= SELECTION_FILELIST;
	      queue_empty(&job);
	      selection_make(pool, &job, list, selflags);
	      if (!job.elements)
		printf("No match\n");
	      else
		{
		  Queue q;
		  int i;
		  queue_init(&q);
		  selection_solvables(pool, &job, &q);
		  for (i = 0; i < q.count; i++)
		    printf("  - %s\n", testcase_solvid2str(pool, q.elements[i]));
		  queue_free(&q);
		}
	    }
	  else if (result || writeresult)
	    {
	      char *myresult, *resultdiff;
	      struct reportsolutiondata reportsolutiondata;
	      memset(&reportsolutiondata, 0, sizeof(reportsolutiondata));
	      if (rescallback)
		{
		  solv->solution_callback = reportsolutioncb;
		  solv->solution_callback_data = &reportsolutiondata;
		}
	      solver_solve(solv, &job);
	      solv->solution_callback = 0;
	      solv->solution_callback_data = 0;
	      if (!resultflags)
		resultflags = TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
	      myresult = testcase_solverresult(solv, resultflags);
	      if (rescallback && reportsolutiondata.result)
		{
		  reportsolutiondata.result = solv_dupjoin(reportsolutiondata.result, myresult, 0);
		  solv_free(myresult);
		  myresult = reportsolutiondata.result;
		}
	      if (writeresult)
		{
		  if (*myresult)
		    {
		      if (writeresult > 1)
			{
			  const char *p;
			  int i;
			  
			  printf("result ");
			  p = "%s";
			  for (i = 0; resultflags2str[i].str; i++)
			    if ((resultflags & resultflags2str[i].flag) != 0)
			      {
			        printf(p, resultflags2str[i].str);
			        p = ",%s";
			      }
			  printf(" <inline>\n");
			  p = myresult;
			  while (*p)
			    {
			      const char *p2 = strchr(p, '\n');
			      p2 = p2 ? p2 + 1 : p + strlen(p);
			      printf("#>%.*s", (int)(p2 - p), p);
			      p = p2;
			    }
			}
		      else
			printf("%s", myresult);
		    }
		}
	      else
		{
		  resultdiff = testcase_resultdiff(result, myresult);
		  if (resultdiff)
		    {
		      printf("Results differ:\n%s", resultdiff);
		      ex = 1;
		      solv_free(resultdiff);
		    }
		}
	      solv_free(result);
	      solv_free(myresult);
	    }
	  else
	    {
	      int pcnt = solver_solve(solv, &job);
	      if (pcnt && solq.count)
		{
		  int i, taken = 0;
		  for (i = 0; i < solq.count; i += 2)
		    {
		      if (solq.elements[i] > 0 && solq.elements[i] <= pcnt)
			if (solq.elements[i + 1] > 0 && solq.elements[i + 1] <=  solver_solution_count(solv, solq.elements[i]))
			  {
			    printf("problem %d: taking solution %d\n", solq.elements[i], solq.elements[i + 1]);
			    solver_take_solution(solv, solq.elements[i], solq.elements[i + 1], &job);
			    taken = 1;
			  }
		    }
		  if (taken)
		    pcnt = solver_solve(solv, &job);
		}
	      if (pcnt)
		{
		  int problem, solution, scnt;
		  printf("Found %d problems:\n", pcnt);
		  for (problem = 1; problem <= pcnt; problem++)
		    {
		      printf("Problem %d:\n", problem);
#if 1
		      solver_printprobleminfo(solv, problem);
#else
		      {
			Queue pq;
			int j;
			queue_init(&pq);
			solver_findallproblemrules(solv, problem, &pq);
			for (j = 0; j < pq.count; j++)
			  solver_printproblemruleinfo(solv, pq.elements[j]);
			queue_free(&pq);
		      }
#endif
		      printf("\n");
		      scnt = solver_solution_count(solv, problem);
		      for (solution = 1; solution <= scnt; solution++)
			{
			  printf("Solution %d:\n", solution);
			  solver_printsolution(solv, problem, solution);
			  printf("\n");
			}
		    }
		}
	      else
		{
		  Transaction *trans = solver_create_transaction(solv);
		  printf("Transaction summary:\n\n");
		  transaction_print(trans);
		  transaction_free(trans);
		}
	    }
	  queue_free(&job);
	  solver_free(solv);
	}
      pool_free(pool);
      fclose(fp);
    }
  queue_free(&solq);
  exit(ex);
}
示例#3
0
int
cc_request_download(cc_t *cc)
{
    return_val_if_fail(cc, -1);
    return_val_if_fail(cc->current_queue == NULL || cc->fetch_leaves == 2, -1);

    queue_t *queue = cc->current_queue;
    int num_returned_bytes;
    while (queue == NULL) {
        queue = queue_get_next_source_for_nick(cc->nick);
        if (queue == NULL) {
            /* no more files to download */
            return -1;
        }

        queue->offset = 0ULL;

        if (queue->is_directory) {
            if (queue_resolve_directory(cc->nick, queue->source_filename, queue->target_filename, NULL) != 0) {
                /* Directory was not directly resolvable, but it should be! */
                /* When the directory is added to the queue, it is directly
                 * resolved if the filelist is directly available. Otherwise
                 * the filelist is queued and should be downloaded before the
                 * directory. */
                WARNING("unresolvable directory [%s] ???", queue->source_filename);

		/* Apparently there is an inconsistency in the queue data.
		 * Instead of risk looping forever trying to resolve the
		 * directory, just remove it.
		 */
                queue_remove_directory(queue->target_filename);
            }
        }
        else if (queue->is_filelist) {
            char *safe_nick = strdup(cc->nick);
            str_replace_set(safe_nick, "/", '_');

            if (cc->has_xmlbzlist) {
                num_returned_bytes = asprintf(&queue->target_filename, "%s/files.xml.%s.bz2", global_working_directory, safe_nick);
                if (num_returned_bytes == -1)
                    DEBUG("asprintf did not return anything");
                queue->source_filename = strdup("files.xml.bz2");
            }
            else {
                num_returned_bytes = asprintf(&queue->target_filename, "%s/MyList.%s.DcLst", global_working_directory, safe_nick);
                if (num_returned_bytes == -1)
                    DEBUG("asprintf did not return anything");
                queue->source_filename = strdup("MyList.DcLst");
            }
            free(safe_nick);

            break;
        }
        else
        {
            struct stat stbuf;

            char *target = 0;
            num_returned_bytes = asprintf(&target, "%s/%s", global_download_directory, queue->target_filename);
            if (num_returned_bytes == -1)
                DEBUG("asprintf did not return anything");
            
            /* Check if the file is already downloaded */
            if (stat(target, &stbuf) == 0) {
                INFO("local file in download dir already exists: [%s]", target);
                /* what if size differs? */
                queue_remove_target(queue->target_filename);
                free(target);
            }
            else {
                free(target);
                num_returned_bytes = asprintf(&target, "%s/%s", global_incomplete_directory, queue->target_filename);
                if (num_returned_bytes == -1)
                    DEBUG("aasprintf did not return anything");

                int rc = stat(target, &stbuf);
                free(target);
                if (rc == 0) {
                    /* file already exists, resume */
                    queue->offset = stbuf.st_size;
                    if (queue->offset >= queue->size) {
                        INFO("local file has larger or equal size than remote,"
                                " can't resume, removing queue");

                        nc_send_download_finished_notification(nc_default(),
                                queue->target_filename);

                        queue_remove_target(queue->target_filename);
                    }
                    else {
                        /* resume download */
                        break;
                    }
                }
                else {
                    /* regular file, doesn't already exist */
                    break;
                }
            }
        }

        /* try again */

        queue_free(queue);
        queue = NULL;
    }

    cc->current_queue = queue;
    if (cc_send_download_request(cc) != 0) {
        cc_close_connection(cc);
        return -1;
    }

    if (queue->is_filelist)
        cc->filesize = 0ULL;
    else
        cc->filesize = queue->size;
    cc->offset = queue->offset;

    /* tell the download queue that we're now handling this request */
    queue_set_active(queue, 1);

    return 0;
}
示例#4
0
文件: net.c 项目: takayuki/al
int
main ()
{
    long numNode = 100;

    puts("Starting tests...");

    bool_t status;

    net_t* netPtr = net_alloc(numNode);
    assert(netPtr);
    bitmap_t* visitedBitmapPtr = bitmap_alloc(numNode);
    assert(visitedBitmapPtr);
    queue_t* workQueuePtr = queue_alloc(-1);
    assert(workQueuePtr);

    assert(!net_isCycle(netPtr));

    long aId = 31;
    long bId = 14;
    long cId = 5;
    long dId = 92;

    net_applyOperation(netPtr, OPERATION_INSERT, aId, bId);
    assert(net_isPath(netPtr, aId, bId, visitedBitmapPtr, workQueuePtr));
    assert(!net_isPath(netPtr, bId, aId, visitedBitmapPtr, workQueuePtr));
    assert(!net_isPath(netPtr, aId, cId, visitedBitmapPtr, workQueuePtr));
    assert(!net_isPath(netPtr, aId, dId, visitedBitmapPtr, workQueuePtr));
    assert(!net_isCycle(netPtr));

    net_applyOperation(netPtr, OPERATION_INSERT, bId, cId);
    net_applyOperation(netPtr, OPERATION_INSERT, aId, cId);
    net_applyOperation(netPtr, OPERATION_INSERT, dId, aId);
    assert(!net_isCycle(netPtr));
    net_applyOperation(netPtr, OPERATION_INSERT, cId, dId);
    assert(net_isCycle(netPtr));
    net_applyOperation(netPtr, OPERATION_REVERSE, cId, dId);
    assert(!net_isCycle(netPtr));
    net_applyOperation(netPtr, OPERATION_REVERSE, dId, cId);
    assert(net_isCycle(netPtr));
    assert(net_isPath(netPtr, aId, dId, visitedBitmapPtr, workQueuePtr));
    net_applyOperation(netPtr, OPERATION_REMOVE, cId, dId);
    assert(!net_isPath(netPtr, aId, dId, visitedBitmapPtr, workQueuePtr));

    bitmap_t* ancestorBitmapPtr = bitmap_alloc(numNode);
    assert(ancestorBitmapPtr);
    status = net_findAncestors(netPtr, cId, ancestorBitmapPtr, workQueuePtr);
    assert(status);
    assert(bitmap_isSet(ancestorBitmapPtr, aId));
    assert(bitmap_isSet(ancestorBitmapPtr, bId));
    assert(bitmap_isSet(ancestorBitmapPtr, dId));
    assert(bitmap_getNumSet(ancestorBitmapPtr) == 3);

    bitmap_t* descendantBitmapPtr = bitmap_alloc(numNode);
    assert(descendantBitmapPtr);
    status = net_findDescendants(netPtr, aId, descendantBitmapPtr, workQueuePtr);
    assert(status);
    assert(bitmap_isSet(descendantBitmapPtr, bId));
    assert(bitmap_isSet(descendantBitmapPtr, cId));
    assert(bitmap_getNumSet(descendantBitmapPtr) == 2);

    bitmap_free(visitedBitmapPtr);
    queue_free(workQueuePtr);
    bitmap_free(ancestorBitmapPtr);
    bitmap_free(descendantBitmapPtr);
    net_free(netPtr);

    random_t* randomPtr = random_alloc();
    assert(randomPtr);
    netPtr = net_alloc(numNode);
    assert(netPtr);
    net_generateRandomEdges(netPtr, 10, 10, randomPtr);
    net_free(netPtr);

    puts("All tests passed.");

    return 0;
}
示例#5
0
/*----------------------------------------------------------------------*/
void sys_mbox_free(sys_mbox_t mbox)
{
  queue_free(mbox);
}
示例#6
0
文件: bnfa.c 项目: lightduer/openurl
/*
 *   Build a non-deterministic finite automata using Aho-Corasick construction
 *   The keyword trie must already be built via bnfa_add_pattern_states()
 */
static int bnfa_build_nfa(bnfa_struct_t * bnfa)
{
	int             r, s, i;
	QUEUE           q, *queue = &q;
	bnfa_state_t     *fail_state = bnfa->fail_state;
	bnfa_match_node_t **match_list = bnfa->match_list;
	bnfa_match_node_t  *mlist;
	bnfa_match_node_t  *px;

	/* Init a Queue */
	queue_init(queue);

	/* Add the state 0 transitions 1st,
	 * the states at depth 1, fail to state 0
	 */
	for (i = 0; i < bnfa->alphabet_size; i++)
	{
		/* note that state zero deos not fail,
		 *  it just returns 0..nstates-1
		 */
		s = bnfa_list_get_next_state(bnfa, 0, i);
		if (s) /* don't bother adding state zero */
		{
			if (queue_add(queue, s))
			{
				queue_free(queue);
				return -1;
			}
			fail_state[s] = 0;
		}
	}

	/* Build the fail state successive layer of transitions */
	while (queue_count(queue) > 0)
	{
		r = queue_remove(queue);

		/* Find Final States for any Failure */
		for (i = 0; i < bnfa->alphabet_size; i++)
		{
			int fs, next;

			s = bnfa_list_get_next_state(bnfa,r,i);

			if (s == (int)BNFA_FAIL_STATE)
				continue;

			if (queue_add(queue, s))
			{
				queue_free(queue);
				return -1;
			}

			fs = fail_state[r];

			/*
			 *  Locate the next valid state for 'i' starting at fs
			 */
			while ((next=bnfa_list_get_next_state(bnfa,fs,i)) == (int)BNFA_FAIL_STATE)
			{
				fs = fail_state[fs];
			}

			/*
			 *  Update 's' state failure state to point to the next valid state
			 */
			fail_state[s] = next;

			/*
			 *  Copy 'next'states match_list into 's' states match_list,
			 *  we just create a new list nodes, the patterns are not copied.
			 */
			for (mlist = match_list[next];mlist;mlist = mlist->next)
			{
				/* Dup the node, don't copy the data */
				px = BNFA_MALLOC(sizeof(bnfa_match_node_t));
				if (!px)
				{
					queue_free(queue);
					return 0;
				}

				px->data = mlist->data;

				px->next = match_list[s]; /* insert at head */

				match_list[s] = px;
			}
		}
	}

	/* Clean up the queue */
	queue_free(queue);

	/* optimize the failure states */
	if (bnfa->opt)
		bnfa_opt_nfa(bnfa);

	return 0;
}
示例#7
0
/* Listen for a connection from somebody else. When communication link is
 * created return a minisocket_t through which the communication can be made
 * from now on.
 *
 * The argument "port" is the port number on the local machine to which the
 * client will connect.
 *
 * Return value: the minisocket_t created, otherwise NULL with the errorcode
 * stored in the "error" variable.
 */
minisocket_t minisocket_server_create(int port, minisocket_error *error)
{
  minisocket_t new_sock;
  interrupt_level_t l;
  network_interrupt_arg_t * pkt;
  resend_arg* resend_alarm_arg;
  char tmp; 

  //check valid portnum
  if (port < 0 || port >= CLIENT_START){
    *error = SOCKET_INVALIDPARAMS;
    return NULL;
  }

  //check port in use
  semaphore_P(server_lock);

  //printf("calling server_create at port %d.\n", port);
  //printf("value at port %d is %li.\n", port, (long)sock_array[port]);
  if (sock_array[port] != NULL){
    *error = SOCKET_PORTINUSE;
    return NULL;
  }
  new_sock = (minisocket_t)malloc(sizeof(struct minisocket));
  if (!new_sock){
    semaphore_V(server_lock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->pkt_ready_sem = semaphore_create();
  if (!(new_sock->pkt_ready_sem)){
    semaphore_V(server_lock);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->pkt_q = queue_new();
  if (!(new_sock->pkt_q)){
    semaphore_V(server_lock);
    semaphore_destroy(new_sock->pkt_ready_sem);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->sock_lock = semaphore_create();
  if (!(new_sock->sock_lock)){
    semaphore_V(server_lock);
    free(new_sock->pkt_ready_sem);
    queue_free(new_sock->pkt_q);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->ack_ready_sem = semaphore_create();
  if (!(new_sock->ack_ready_sem)){
    semaphore_V(server_lock);
    semaphore_destroy(new_sock->pkt_ready_sem);
    queue_free(new_sock->pkt_q);
    semaphore_destroy(new_sock->sock_lock);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  semaphore_initialize(new_sock->pkt_ready_sem, 0);
  semaphore_initialize(new_sock->ack_ready_sem, 0);
  semaphore_initialize(new_sock->sock_lock, 1);

  new_sock->curr_state = LISTEN;
  new_sock->try_count = 0;
  new_sock->curr_ack = 0;
  new_sock->curr_seq = 1;
  new_sock->resend_alarm = NULL; // no alarm set
  new_sock->src_port = port;
  new_sock->dst_port = -1; // not paired with client
  network_address_blankify(new_sock->dst_addr); // not paired with client

  sock_array[port] = new_sock;
  semaphore_V(server_lock);
 
  resend_alarm_arg = (resend_arg*)calloc(1, sizeof(resend_arg));
  while (1) {
    // wait for MSG_SYN
    semaphore_P(new_sock->ack_ready_sem);
    l = set_interrupt_level(DISABLED);
 
    switch (new_sock->curr_state) {
    case CONNECTING:  
      minisocket_send_ctrl(MSG_SYNACK, new_sock, error);

      resend_alarm_arg->sock = new_sock;
      resend_alarm_arg->msg_type = MSG_SYNACK;
      resend_alarm_arg->data_len = 0;
      resend_alarm_arg->data = &tmp; //placeholder
      resend_alarm_arg->error = error; 
      new_sock->resend_alarm = set_alarm(RESEND_TIME_UNIT, minisocket_resend, resend_alarm_arg, minithread_time());
      
      new_sock->curr_state = MSG_WAIT;
      set_interrupt_level(l);
      break;

    case CONNECTED:
      // must have gotten a MSG_ACK 
      //printf("in server_create, SUCCESS!\n");
      new_sock->try_count = 0;
      deregister_alarm(new_sock->resend_alarm);
      new_sock->resend_alarm = NULL;
      *error = SOCKET_NOERROR;
      set_interrupt_level(l);
      //printf("exiting server_create\n");
      free(resend_alarm_arg);
      return new_sock;
      break;

    case EXIT: default:
      *error = SOCKET_SENDERROR;
      // clean out the queue
      while (queue_dequeue(new_sock->pkt_q,(void**)&pkt) != -1){
        free(pkt);
      }
      new_sock->curr_state = LISTEN;
      new_sock->curr_ack = 0;
      new_sock->curr_seq = 1;
      set_interrupt_level(l);
      break;
    }
  }
  free(resend_alarm_arg);
  return new_sock;
}
void free_moving_average(Moving_Average *self) {
	puts("freeing MA");
	queue_free(self->data);
	free(self);
	self = NULL;
}
示例#9
0
文件: acsmx.c 项目: bananatfx/beamend
/*
 *   Build Non-Deterministic Finite Automata
 */ 
static void Build_NFA (ACSM_STRUCT * acsm) 
{
	int r, s;
	int i;
	QUEUE q, *queue = &q;
	ACSM_PATTERN * mlist=0;
	ACSM_PATTERN * px=0;

	/* Init a Queue */ 
	queue_init (queue);

	/* Add the state 0 transitions 1st */ 
	for (i = 0; i < ALPHABET_SIZE; i++)
	{
		s = acsm->acsmStateTable[0].NextState[i];
		if (s)
		{
			queue_add (queue, s);
			acsm->acsmStateTable[s].FailState = 0;
		}
	}

	/* Build the fail state transitions for each valid state */ 
	while (queue_count (queue) > 0)
	{
		r = queue_remove (queue);

		/* Find Final States for any Failure */ 
		for (i = 0; i < ALPHABET_SIZE; i++)
		{
			int fs, next;
			if ((s = acsm->acsmStateTable[r].NextState[i]) != ACSM_FAIL_STATE)
			{
				queue_add (queue, s);
				fs = acsm->acsmStateTable[r].FailState;

				/* 
				 *  Locate the next valid state for 'i' starting at s 
				 */ 
				while ((next=acsm->acsmStateTable[fs].NextState[i]) ==
						ACSM_FAIL_STATE)
				{
					fs = acsm->acsmStateTable[fs].FailState;
				}

				/*
				 *  Update 's' state failure state to point to the next valid state
				 */ 
				acsm->acsmStateTable[s].FailState = next;

				/*
				 *  Copy 'next'states MatchList to 's' states MatchList, 
				 *  we copy them so each list can be AC_FREE'd later,
				 *  else we could just manipulate pointers to fake the copy.
				 */ 
				for (mlist  = acsm->acsmStateTable[next].MatchList; 
						mlist != NULL ;
						mlist  = mlist->next)
				{
					px = CopyMatchListEntry (mlist);

					if( !px )
					{
						//FatalError("*** Out of memory Initializing Aho Corasick in acsmx.c ****");
					}

					/* Insert at front of MatchList */ 
					px->next = acsm->acsmStateTable[s].MatchList;
					acsm->acsmStateTable[s].MatchList = px;
				}
			}
		}
	}

	/* Clean up the queue */ 
	queue_free (queue);
}
示例#10
0
文件: advisory.c 项目: Xake/hawkey
void
hy_advisorylist_free(HyAdvisoryList advisorylist)
{
    queue_free(&advisorylist->queue);
    solv_free(advisorylist);
}
示例#11
0
文件: solv.c 项目: myungjoo/libsolv
int
main(int argc, char **argv)
{
  Pool *pool;
  Repo *commandlinerepo = 0;
  Id *commandlinepkgs = 0;
  Id p;
  struct repoinfo *repoinfos, installedrepoinfo;
  int nrepoinfos = 0;
  int mainmode = 0, mode = 0;
  int i, newpkgs;
  Queue job, checkq;
  Solver *solv = 0;
  Transaction *trans;
  FILE **newpkgsfps;
  Queue repofilter;
  Queue kindfilter;
  Queue archfilter;
  int archfilter_src = 0;
  int cleandeps = 0;
  int forcebest = 0;
  char *rootdir = 0;
  char *keyname = 0;
  int keyname_depstr = 0;
  int debuglevel = 0;
  int answer, acnt = 0;

  argc--;
  argv++;
  while (argc && !strcmp(argv[0], "-d"))
    {
      debuglevel++;
      argc--;
      argv++;
    }
  if (!argv[0])
    usage(1);
  if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in"))
    {
      mainmode = MODE_INSTALL;
      mode = SOLVER_INSTALL;
    }
#if defined(SUSE) || defined(FEDORA)
  else if (!strcmp(argv[0], "patch"))
    {
      mainmode = MODE_PATCH;
      mode = SOLVER_INSTALL;
    }
#endif
  else if (!strcmp(argv[0], "erase") || !strcmp(argv[0], "rm"))
    {
      mainmode = MODE_ERASE;
      mode = SOLVER_ERASE;
    }
  else if (!strcmp(argv[0], "list") || !strcmp(argv[0], "ls"))
    {
      mainmode = MODE_LIST;
      mode = 0;
    }
  else if (!strcmp(argv[0], "info"))
    {
      mainmode = MODE_INFO;
      mode = 0;
    }
  else if (!strcmp(argv[0], "search") || !strcmp(argv[0], "se"))
    {
      mainmode = MODE_SEARCH;
      mode = 0;
    }
  else if (!strcmp(argv[0], "verify"))
    {
      mainmode = MODE_VERIFY;
      mode = SOLVER_VERIFY;
    }
  else if (!strcmp(argv[0], "update") || !strcmp(argv[0], "up"))
    {
      mainmode = MODE_UPDATE;
      mode = SOLVER_UPDATE;
    }
  else if (!strcmp(argv[0], "dist-upgrade") || !strcmp(argv[0], "dup"))
    {
      mainmode = MODE_DISTUPGRADE;
      mode = SOLVER_DISTUPGRADE;
    }
  else if (!strcmp(argv[0], "repos") || !strcmp(argv[0], "repolist") || !strcmp(argv[0], "lr"))
    {
      mainmode = MODE_REPOLIST;
      mode = 0;
    }
  else
    usage(1);

  for (;;)
    {
      if (argc > 2 && !strcmp(argv[1], "--root"))
	{
	  rootdir = argv[2];
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 1 && !strcmp(argv[1], "--clean"))
	{
	  cleandeps = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 1 && !strcmp(argv[1], "--best"))
	{
	  forcebest = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 1 && !strcmp(argv[1], "--depstr"))
	{
	  keyname_depstr = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 2 && !strcmp(argv[1], "--keyname"))
	{
	  keyname = argv[2];
	  argc -= 2;
	  argv += 2;
	}
      else
	break;
    }

  set_userhome();
  pool = pool_create();
  pool_set_rootdir(pool, rootdir);

#if 0
  {
    const char *langs[] = {"de_DE", "de", "en"};
    pool_set_languages(pool, langs, sizeof(langs)/sizeof(*langs));
  }
#endif

  pool_setloadcallback(pool, load_stub, 0);
#ifdef SUSE
  pool->nscallback = nscallback;
#endif
  if (debuglevel)
    pool_setdebuglevel(pool, debuglevel);
  setarch(pool);
  pool_set_flag(pool, POOL_FLAG_ADDFILEPROVIDESFILTERED, 1);
  repoinfos = read_repoinfos(pool, &nrepoinfos);
  sort_repoinfos(repoinfos, nrepoinfos);

  if (mainmode == MODE_REPOLIST)
    {
      int j = 1;
      for (i = 0; i < nrepoinfos; i++)
	{
	  struct repoinfo *cinfo = repoinfos + i;
	  if (!cinfo->enabled)
	    continue;
	  printf("%d: %-20s %s (prio %d)\n", j++, cinfo->alias, cinfo->name, cinfo->priority);
	}
      exit(0);
    }
  memset(&installedrepoinfo, 0, sizeof(installedrepoinfo));
  if (!read_installed_repo(&installedrepoinfo, pool))
    exit(1);
  read_repos(pool, repoinfos, nrepoinfos);

  /* setup filters */
  queue_init(&repofilter);
  queue_init(&kindfilter);
  queue_init(&archfilter);
  while (argc > 1)
    {
      if (!strcmp(argv[1], "-i"))
	{
	  queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO, pool->installed->repoid);
	  argc--;
	  argv++;
	}
      else if (argc > 2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "--repo")))
	{
	  Id repoid = find_repo(argv[2], pool, repoinfos, nrepoinfos);
	  if (!repoid)
	    {
	      fprintf(stderr, "%s: no such repo\n", argv[2]);
	      exit(1);
	    }
	  /* SETVENDOR is actually wrong but useful */
	  queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO | SOLVER_SETVENDOR, repoid);
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 2 && !strcmp(argv[1], "--arch"))
	{
	  if (!strcmp(argv[2], "src") || !strcmp(argv[2], "nosrc"))
	    archfilter_src = 1;
	  queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, argv[2], 1), REL_ARCH, 1));
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 2 && (!strcmp(argv[1], "-t") || !strcmp(argv[1], "--type")))
	{
	  const char *kind = argv[2];
	  if (!strcmp(kind, "srcpackage"))
	    {
	      /* hey! should use --arch! */
	      queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, ARCH_SRC, REL_ARCH, 1));
	      archfilter_src = 1;
	      argc -= 2;
	      argv += 2;
	      continue;
	    }
	  if (!strcmp(kind, "package"))
	    kind = "";
	  if (!strcmp(kind, "all"))
	    queue_push2(&kindfilter, SOLVER_SOLVABLE_ALL, 0);
	  else
	    queue_push2(&kindfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, kind, 1), REL_KIND, 1));
	  argc -= 2;
	  argv += 2;
	}
      else
	break;
    }

  if (mainmode == MODE_SEARCH)
    {
      Queue sel, q;
      Dataiterator di;
      if (argc != 2)
	usage(1);
      pool_createwhatprovides(pool);
      queue_init(&sel);
      dataiterator_init(&di, pool, 0, 0, 0, argv[1], SEARCH_SUBSTRING|SEARCH_NOCASE);
      dataiterator_set_keyname(&di, SOLVABLE_NAME);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_set_keyname(&di, SOLVABLE_SUMMARY);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_set_keyname(&di, SOLVABLE_DESCRIPTION);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_free(&di);
      if (repofilter.count)
	selection_filter(pool, &sel, &repofilter);
	
      queue_init(&q);
      selection_solvables(pool, &sel, &q);
      queue_free(&sel);
      for (i = 0; i < q.count; i++)
	{
	  Solvable *s = pool_id2solvable(pool, q.elements[i]);
	  printf("  - %s [%s]: %s\n", pool_solvable2str(pool, s), s->repo->name, solvable_lookup_str(s, SOLVABLE_SUMMARY));
	}
      queue_free(&q);
      exit(0);
    }

  /* process command line packages */
  if (mainmode == MODE_LIST || mainmode == MODE_INFO || mainmode == MODE_INSTALL)
    {
      for (i = 1; i < argc; i++)
	{
	  if (!is_cmdline_package((const char *)argv[i]))
	    continue;
	  if (access(argv[i], R_OK))
	    {
	      perror(argv[i]);
	      exit(1);
	    }
	  if (!commandlinepkgs)
	    commandlinepkgs = solv_calloc(argc, sizeof(Id));
	  if (!commandlinerepo)
	    commandlinerepo = repo_create(pool, "@commandline");
	  p = add_cmdline_package(commandlinerepo, (const char *)argv[i]);
	  if (!p)
	    {
	      fprintf(stderr, "could not add '%s'\n", argv[i]);
	      exit(1);
	    }
	  commandlinepkgs[i] = p;
	}
      if (commandlinerepo)
	repo_internalize(commandlinerepo);
    }

#if defined(ENABLE_RPMDB)
  if (pool->disttype == DISTTYPE_RPM)
    addfileprovides(pool);
#endif
#ifdef SUSE
  add_autopackages(pool);
#endif
  pool_createwhatprovides(pool);

  if (keyname)
    keyname = solv_dupjoin("solvable:", keyname, 0);
  queue_init(&job);
  for (i = 1; i < argc; i++)
    {
      Queue job2;
      int flags, rflags;

      if (commandlinepkgs && commandlinepkgs[i])
	{
	  queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]);
	  continue;
	}
      queue_init(&job2);
      flags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_GLOB;
      flags |= SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL;
      if (kindfilter.count)
	flags |= SELECTION_SKIP_KIND;
      if (mode == MODE_LIST || archfilter_src)
	flags |= SELECTION_WITH_SOURCE;
      if (argv[i][0] == '/')
	flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0);
      if (!keyname)
        rflags = selection_make(pool, &job2, argv[i], flags);
      else
	{
	  if (keyname_depstr)
	    flags |= SELECTION_MATCH_DEPSTR;
          rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
	}
      if (repofilter.count)
	selection_filter(pool, &job2, &repofilter);
      if (archfilter.count)
	selection_filter(pool, &job2, &archfilter);
      if (kindfilter.count)
	selection_filter(pool, &job2, &kindfilter);
      if (!job2.count)
	{
	  flags |= SELECTION_NOCASE;
	  if (!keyname)
            rflags = selection_make(pool, &job2, argv[i], flags);
	  else
	    rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
	  if (repofilter.count)
	    selection_filter(pool, &job2, &repofilter);
	  if (archfilter.count)
	    selection_filter(pool, &job2, &archfilter);
	  if (kindfilter.count)
	    selection_filter(pool, &job2, &kindfilter);
	  if (job2.count)
	    printf("[ignoring case for '%s']\n", argv[i]);
	}
      if (!job2.count)
	{
	  fprintf(stderr, "nothing matches '%s'\n", argv[i]);
	  exit(1);
	}
      if (rflags & SELECTION_FILELIST)
        printf("[using file list match for '%s']\n", argv[i]);
      if (rflags & SELECTION_PROVIDES)
	printf("[using capability match for '%s']\n", argv[i]);
      queue_insertn(&job, job.count, job2.count, job2.elements);
      queue_free(&job2);
    }
  keyname = solv_free(keyname);

  if (!job.count && (mainmode == MODE_UPDATE || mainmode == MODE_DISTUPGRADE || mainmode == MODE_VERIFY || repofilter.count || archfilter.count || kindfilter.count))
    {
      queue_push2(&job, SOLVER_SOLVABLE_ALL, 0);
      if (repofilter.count)
	selection_filter(pool, &job, &repofilter);
      if (archfilter.count)
	selection_filter(pool, &job, &archfilter);
      if (kindfilter.count)
	selection_filter(pool, &job, &kindfilter);
    }
  queue_free(&repofilter);
  queue_free(&archfilter);
  queue_free(&kindfilter);

  if (!job.count && mainmode != MODE_PATCH)
    {
      printf("no package matched\n");
      exit(1);
    }

  if (mainmode == MODE_LIST || mainmode == MODE_INFO)
    {
      /* list mode, no solver needed */
      Queue q;
      queue_init(&q);
      for (i = 0; i < job.count; i += 2)
	{
	  int j;
	  queue_empty(&q);
	  pool_job2solvables(pool, &q, job.elements[i], job.elements[i + 1]);
	  for (j = 0; j < q.count; j++)
	    {
	      Solvable *s = pool_id2solvable(pool, q.elements[j]);
	      if (mainmode == MODE_INFO)
		{
		  const char *str;
		  printf("Name:        %s\n", pool_solvable2str(pool, s));
		  printf("Repo:        %s\n", s->repo->name);
		  printf("Summary:     %s\n", solvable_lookup_str(s, SOLVABLE_SUMMARY));
		  str = solvable_lookup_str(s, SOLVABLE_URL);
		  if (str)
		    printf("Url:         %s\n", str);
		  str = solvable_lookup_str(s, SOLVABLE_LICENSE);
		  if (str)
		    printf("License:     %s\n", str);
		  printf("Description:\n%s\n", solvable_lookup_str(s, SOLVABLE_DESCRIPTION));
		  printf("\n");
		}
	      else
		{
#if 1
		  const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de", 1);
#else
		  const char *sum = solvable_lookup_str_poollang(s, SOLVABLE_SUMMARY);
#endif
		  printf("  - %s [%s]\n", pool_solvable2str(pool, s), s->repo->name);
		  if (sum)
		    printf("    %s\n", sum);
		}
	    }
	}
      queue_free(&q);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(0);
    }

#if defined(SUSE) || defined(FEDORA)
  if (mainmode == MODE_PATCH)
    add_patchjobs(pool, &job);
#endif

  // add mode
  for (i = 0; i < job.count; i += 2)
    {
      job.elements[i] |= mode;
      if (mode == SOLVER_UPDATE && pool_isemptyupdatejob(pool, job.elements[i], job.elements[i + 1]))
	job.elements[i] ^= SOLVER_UPDATE ^ SOLVER_INSTALL;
      if (cleandeps)
        job.elements[i] |= SOLVER_CLEANDEPS;
      if (forcebest)
        job.elements[i] |= SOLVER_FORCEBEST;
    }

  // multiversion test
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae", 1));
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-base", 1));
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-extra", 1));
#if 0
  queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
  queue_push2(&job, SOLVER_ERASE|SOLVER_CLEANDEPS|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
#endif

rerunsolver:
  solv = solver_create(pool);
  solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
#ifdef FEDORA
  solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
#endif
  if (mainmode == MODE_ERASE)
    solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1);	/* don't nag */
  solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1);

  for (;;)
    {
      Id problem, solution;
      int pcnt, scnt;

      if (!solver_solve(solv, &job))
	break;
      pcnt = solver_problem_count(solv);
      printf("Found %d problems:\n", pcnt);
      for (problem = 1; problem <= pcnt; problem++)
	{
	  int take = 0;
	  printf("Problem %d/%d:\n", problem, pcnt);
	  solver_printprobleminfo(solv, problem);
	  printf("\n");
	  scnt = solver_solution_count(solv, problem);
	  for (solution = 1; solution <= scnt; solution++)
	    {
	      printf("Solution %d:\n", solution);
	      solver_printsolution(solv, problem, solution);
	      printf("\n");
	    }
	  for (;;)
	    {
	      char inbuf[128], *ip;
	      printf("Please choose a solution: ");
	      fflush(stdout);
	      *inbuf = 0;
	      if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
		{
		  printf("Abort.\n");
		  exit(1);
		}
	      while (*ip == ' ' || *ip == '\t')
		ip++;
	      if (*ip >= '0' && *ip <= '9')
		{
		  take = atoi(ip);
		  if (take >= 1 && take <= scnt)
		    break;
		}
	      if (*ip == 's')
		{
		  take = 0;
		  break;
		}
	      if (*ip == 'q')
		{
		  printf("Abort.\n");
		  exit(1);
		}
	    }
	  if (!take)
	    continue;
	  solver_take_solution(solv, problem, take, &job);
	}
    }

  trans = solver_create_transaction(solv);
  if (!trans->steps.count)
    {
      printf("Nothing to do.\n");
      transaction_free(trans);
      solver_free(solv);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(1);
    }

  /* display transaction to the user and ask for confirmation */
  printf("\n");
  printf("Transaction summary:\n\n");
  transaction_print(trans);
#if defined(SUSE)
  showdiskusagechanges(trans);
#endif
  printf("install size change: %d K\n", transaction_calc_installsizechange(trans));
  printf("\n");

  acnt = solver_alternatives_count(solv);
  if (acnt)
    {
      if (acnt == 1)
        printf("Have one alternative:\n");
      else
        printf("Have %d alternatives:\n", acnt);
      for (i = 1; i <= acnt; i++)
	{
	  Id id, from;
	  int atype = solver_get_alternative(solv, i, &id, &from, 0, 0, 0);
	  printf("  - %s\n", solver_alternative2str(solv, atype, id, from));
	}
      printf("\n");
      answer = yesno("OK to continue (y/n/a)? ", 'a');
    }
  else
    answer = yesno("OK to continue (y/n)? ", 0);
  if (answer == 'a')
    {
      Queue choicesq;
      Queue answerq;
      Id id, from, chosen;
      int j;

      queue_init(&choicesq);
      queue_init(&answerq);
      for (i = 1; i <= acnt; i++)
	{
	  int atype = solver_get_alternative(solv, i, &id, &from, &chosen, &choicesq, 0);
	  printf("\n%s\n", solver_alternative2str(solv, atype, id, from));
	  for (j = 0; j < choicesq.count; j++)
	    {
	      Id p = choicesq.elements[j];
	      if (p < 0)
		p = -p;
	      queue_push(&answerq, p);
	      printf("%6d: %s\n", answerq.count, pool_solvid2str(pool, p));
	    }
	}
      queue_free(&choicesq);
      printf("\n");
      for (;;)
	{
	  char inbuf[128], *ip;
	  int neg = 0;
	  printf("OK to continue (y/n), or number to change alternative: ");
	  fflush(stdout);
	  *inbuf = 0;
	  if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
	    {
	      printf("Abort.\n");
	      exit(1);
	    }
	  while (*ip == ' ' || *ip == '\t')
	    ip++;
	  if (*ip == '-' && ip[1] >= '0' && ip[1] <= '9')
	    {
	      neg = 1;
	      ip++;
	    }
	  if (*ip >= '0' && *ip <= '9')
	    {
	      int take = atoi(ip);
	      if (take > 0 && take <= answerq.count)
		{
		  Id p = answerq.elements[take - 1];
		  queue_free(&answerq);
		  queue_push2(&job, (neg ? SOLVER_DISFAVOR : SOLVER_FAVOR) | SOLVER_SOLVABLE_NAME, pool->solvables[p].name);
		  solver_free(solv);
		  solv = 0;
		  goto rerunsolver;
		  break;
		}
	    }
	  if (*ip == 'n' || *ip == 'y')
	    {
	      answer = *ip == 'n' ? 0 : *ip;
	      break;
	    }
	}
      queue_free(&answerq);
    }
  if (!answer)
    {
      printf("Abort.\n");
      transaction_free(trans);
      solver_free(solv);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(1);
    }

  /* download all new packages */
  queue_init(&checkq);
  newpkgs = transaction_installedresult(trans, &checkq);
  newpkgsfps = 0;
  if (newpkgs)
    {
      int downloadsize = 0;
      for (i = 0; i < newpkgs; i++)
	{
	  Solvable *s;

	  p = checkq.elements[i];
	  s = pool_id2solvable(pool, p);
	  downloadsize += solvable_lookup_sizek(s, SOLVABLE_DOWNLOADSIZE, 0);
	}
      printf("Downloading %d packages, %d K\n", newpkgs, downloadsize);
      newpkgsfps = solv_calloc(newpkgs, sizeof(*newpkgsfps));
      for (i = 0; i < newpkgs; i++)
	{
	  const char *loc;
	  Solvable *s;
	  struct repoinfo *cinfo;

	  p = checkq.elements[i];
	  s = pool_id2solvable(pool, p);
	  if (s->repo == commandlinerepo)
	    {
	      loc = solvable_lookup_location(s, 0);
	      if (!loc)
		continue;
	      if (!(newpkgsfps[i] = fopen(loc, "r")))
		{
		  perror(loc);
		  exit(1);
		}
	      putchar('.');
	      continue;
	    }
	  cinfo = s->repo->appdata;
	  if (!cinfo || cinfo->type == TYPE_INSTALLED)
	    {
	      printf("%s: no repository information\n", s->repo->name);
	      exit(1);
	    }
	  loc = solvable_lookup_location(s, 0);
	  if (!loc)
	     continue;	/* pseudo package? */
#if defined(ENABLE_RPMDB)
	  if (pool->installed && pool->installed->nsolvables)
	    {
	      if ((newpkgsfps[i] = trydeltadownload(s, loc)) != 0)
		{
		  putchar('d');
		  fflush(stdout);
		  continue;		/* delta worked! */
		}
	    }
#endif
	  if ((newpkgsfps[i] = downloadpackage(s, loc)) == 0)
	    {
	      printf("\n%s: %s not found in repository\n", s->repo->name, loc);
	      exit(1);
	    }
	  putchar('.');
	  fflush(stdout);
	}
      putchar('\n');
    }

#if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA))
  /* check for file conflicts */
  if (newpkgs)
    {
      Queue conflicts;
      queue_init(&conflicts);
      if (checkfileconflicts(pool, &checkq, newpkgs, newpkgsfps, &conflicts))
	{
	  if (yesno("Re-run solver (y/n/q)? ", 0))
	    {
	      for (i = 0; i < newpkgs; i++)
		if (newpkgsfps[i])
		  fclose(newpkgsfps[i]);
	      newpkgsfps = solv_free(newpkgsfps);
	      solver_free(solv);
	      solv = 0;
	      pool_add_fileconflicts_deps(pool, &conflicts);
	      queue_free(&conflicts);
	      goto rerunsolver;
	    }
	}
      queue_free(&conflicts);
    }
#endif

  /* and finally commit the transaction */
  printf("Committing transaction:\n\n");
  transaction_order(trans, 0);
  for (i = 0; i < trans->steps.count; i++)
    {
      int j;
      FILE *fp;
      Id type;

      p = trans->steps.elements[i];
      type = transaction_type(trans, p, SOLVER_TRANSACTION_RPM_ONLY);
      switch(type)
	{
	case SOLVER_TRANSACTION_ERASE:
	  printf("erase %s\n", pool_solvid2str(pool, p));
	  commit_transactionelement(pool, type, p, 0);
	  break;
	case SOLVER_TRANSACTION_INSTALL:
	case SOLVER_TRANSACTION_MULTIINSTALL:
	  printf("install %s\n", pool_solvid2str(pool, p));
	  for (j = 0; j < newpkgs; j++)
	    if (checkq.elements[j] == p)
	      break;
	  fp = j < newpkgs ? newpkgsfps[j] : 0;
	  if (!fp)
	    continue;
	  commit_transactionelement(pool, type, p, fp);
	  fclose(fp);
	  newpkgsfps[j] = 0;
	  break;
	default:
	  break;
	}
    }

  for (i = 0; i < newpkgs; i++)
    if (newpkgsfps[i])
      fclose(newpkgsfps[i]);
  solv_free(newpkgsfps);
  queue_free(&checkq);
  transaction_free(trans);
  solver_free(solv);
  queue_free(&job);
  pool_free(pool);
  free_repoinfos(repoinfos, nrepoinfos);
  solv_free(commandlinepkgs);
  exit(0);
}
示例#12
0
void minisocket_destroy(minisocket_t minisocket, int send_FIN)
{
	int i;
	int threads_waiting;
	int port_number;
	minisocket_error error;
	interrupt_level_t prev_level;

	if (minisocket == NULL)
	{
		return;
	}
	port_number = minisocket->port_number;

	semaphore_P(destroy_sem);

	// Basically, we need the socket's mutex to perform close, as we don't
	// want to close while someone is reading from the buffer or sending something.
	// However, the ms_receive() function acquires the mutex, and then may end
	// up waiting on socket->packet_ready. Therefore, we need to first signal 
	// packet_ready before we can get the mutex in some cases. Only one thread 
	// at a time is ever waiting on socket ready - we may end up letting two
	// pass it as we call it again in minisocket_destroy(), but we set the waiting
	// status to a value that the receive & send functions will detect and cause
	// their function calls to return with a failure. Note that we couldn't set
	// socket->status to TCP_PORT_CLOSING just yet, as that would cause the FIN
	// transmit to fail in our transmit_packet() function. Therefore, we just 
	// created a new waiting status for it.
	minisocket->waiting = TCP_PORT_WAITING_CLOSE;

	// Check if this is already destroyed
	if (minisockets[port_number] == NULL)
	{
		return;
	}

	// Only one thread will ever be waiting on this (b/c it's in a mutex), so
	// just do it once to wake up any thread waiting on it in receive()
	semaphore_V(minisocket->packet_ready);	

	// Wait for the socket mutex
		// This ensures that any currently executing send() finishes
		// This also ensures that anyone who is currently receiving from buffer finishes
	semaphore_P(minisocket->mutex);

	// Another thread already ran destroy, so we can just return
	// Not needed, but won't remove since we're running low on time and don't
	// want to break anything, just in case....
	if (minisockets[port_number] == NULL)
	{
		return;
	}

	// Send a FIN if needed
	if (send_FIN == 1)
	{
		transmit_packet(minisocket, minisocket->dst_addr, minisocket->dst_port, 
							1, MSG_FIN, 0, NULL, &error);
	}

	// Eensure we have the status set correctly so the threads we wake know what
	// is happening
	minisocket->status = TCP_PORT_CLOSING;

	// Awake all threads waiting on mutex - they'll see we're closing and fail
	threads_waiting = minisocket->num_waiting_on_mutex;
	for (i = 0; i < threads_waiting; i++)
	{
		semaphore_V(minisocket->mutex);
	}

	// Remove the port from the minisockets pool
	minisockets[minisocket->port_number] = NULL;

	// NO NEED TO SYNCHRONIZE THIS STUFF WITH THE INTERRUPT HANDLER 
	// This is because, if we get interrupted here, the above line will tell
	// the IH that this socket is closed, so it won't access any of the stuff
	// we're about to free

	// Free all the sems
	prev_level = set_interrupt_level(DISABLED);
	semaphore_destroy(minisocket->wait_for_ack_sem);
	semaphore_destroy(minisocket->mutex);
	semaphore_destroy(minisocket->packet_ready);
	
	// Free the data buffer
	if (minisocket->data_len != 0)
		free(minisocket->data_buffer);

	// Free the queue
	queue_free(minisocket->waiting_packets);
	set_interrupt_level(prev_level);

	// Free the socket itself
	free(minisocket);

	semaphore_V(destroy_sem);
}
示例#13
0
int
repo_add_autopattern(Repo *repo, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data = 0;
  Solvable *s, *s2;
  Queue patq, patq2;
  Queue prdq, prdq2;
  Id p;
  Id pattern_id, product_id;
  Id autopattern_id = 0, autoproduct_id = 0;
  int i, j;

  queue_init(&patq);
  queue_init(&patq2);
  queue_init(&prdq);
  queue_init(&prdq2);

  pattern_id = pool_str2id(pool, "pattern()", 9);
  product_id = pool_str2id(pool, "product()", 9);
  FOR_REPO_SOLVABLES(repo, p, s)
    {
      const char *n = pool_id2str(pool, s->name);
      if (*n == 'p')
	{
	  if (!strncmp("pattern:", n, 8))
	    {
	      queue_push(&patq, p);
	      continue;
	    }
	  else if (!strncmp("product:", n, 8))
	    {
	      queue_push(&prdq, p);
	      continue;
	    }
	}
      if (s->provides)
	{
	  Id prv, *prvp = repo->idarraydata + s->provides;
	  while ((prv = *prvp++) != 0)            /* go through all provides */
	    if (ISRELDEP(prv))
	      {
	        Reldep *rd = GETRELDEP(pool, prv);
		if (rd->flags != REL_EQ)
		  continue;
		if (rd->name == pattern_id)
		  {
		    queue_push2(&patq2, p, rd->evr);
		    break;
		  }
		if (rd->name == product_id)
		  {
		    queue_push2(&prdq2, p, rd->evr);
		    break;
		  }
	      }
	}
    }
  for (i = 0; i < patq2.count; i += 2)
    {
      const char *pn = 0;
      char *newname;
      Id name, prv, *prvp;
      const char *str;
      unsigned long long num;

      s = pool->solvables + patq2.elements[i];
      /* construct new name */
      newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, patq2.elements[i + 1]), 0);
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (name)
	{
	  /* check if we already have that pattern */
	  for (j = 0; j < patq.count; j++)
	    {
	      s2 = pool->solvables + patq.elements[j];
	      if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr)
		break;
	    }
	  if (j < patq.count)
	    continue;	/* yes, do not add again */
	}
      /* new pattern */
      if (!name)
        name = pool_str2id(pool, newname, 1);
      if (!data)
	{
	  repo_internalize(repo);	/* to make that the lookups work */
	  data = repo_add_repodata(repo, flags);
	}
      s2 = pool_id2solvable(pool, repo_add_solvable(repo));
      s = pool->solvables + patq2.elements[i];	/* re-calc pointer */
      s2->name = name;
      s2->arch = s->arch;
      s2->evr = s->evr;
      s2->vendor = s->vendor;
      /* add link requires */
      s2->requires = repo_addid_dep(repo, s2->requires, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1) , 0);
      /* add autopattern provides */
      if (!autopattern_id)
	autopattern_id = pool_str2id(pool, "autopattern()", 1);
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autopattern_id, s->name, REL_EQ, 1), 0);
      /* add self provides */
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0);
      if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_INSTALLTIME, num);
      if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num);
      if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str);
      if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str);
      /* fill in stuff from provides */
      prvp = repo->idarraydata + s->provides;
      while ((prv = *prvp++) != 0)            /* go through all provides */
	{
	  Id evr = 0;
	  if (ISRELDEP(prv))
	    {
	      Reldep *rd = GETRELDEP(pool, prv);
	      if (rd->flags != REL_EQ)
	        continue;
	      prv = rd->name;
	      evr = rd->evr;
	    }
	  pn = pool_id2str(pool, prv);
	  if (strncmp("pattern-", pn, 8) != 0)
	    continue;
	  newname = 0;
	  if (evr)
	    {
	      newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
	      unescape(newname);
	    }
	  if (!strncmp(pn, "pattern-category(", 17) && evr)
	    {
	      char lang[9];
	      int l = strlen(pn);
	      Id langtag;
	      if (l > 17 + 9 || pn[l - 1] != ')')
		continue;
              strncpy(lang, pn + 17, l - 17 - 1);
	      lang[l - 17 - 1] = 0;
	      langtag = SOLVABLE_CATEGORY;
	      if (*lang && strcmp(lang, "en") != 0)
		langtag = pool_id2langid(pool, SOLVABLE_CATEGORY, lang, 1);
	      if (newname[solv_validutf8(newname)] == 0)
	        repodata_set_str(data, s2 - pool->solvables, langtag, newname);
	      else
		{
		  char *ustr = solv_latin1toutf8(newname);
	          repodata_set_str(data, s2 - pool->solvables, langtag, ustr);
		  solv_free(ustr);
		}
	    }
	  else if (!strcmp(pn, "pattern-includes()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_INCLUDES, pool_tmpjoin(pool, "pattern:", newname, 0));
	  else if (!strcmp(pn, "pattern-extends()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_EXTENDS, pool_tmpjoin(pool, "pattern:", newname, 0));
	  else if (!strcmp(pn, "pattern-icon()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ICON, newname);
	  else if (!strcmp(pn, "pattern-order()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ORDER, newname);
	  else if (!strcmp(pn, "pattern-visible()") && !evr)
	    repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE);
	}
    }
  queue_free(&patq);
  queue_free(&patq2);

  if (repo == pool->installed)
    queue_empty(&prdq2);	/* no auto products for installed repos */

  for (i = 0; i < prdq2.count; i += 2)
    {
      const char *pn = 0;
      char *newname;
      Id name, evr = 0, prv, *prvp;
      const char *str;
      unsigned long long num;

      s = pool->solvables + prdq2.elements[i];
      /* construct new name */
      newname = pool_tmpjoin(pool, "product(", pool_id2str(pool, prdq2.elements[i + 1]), ")");
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (!name)
	continue;	/* must have it in provides! */
      prvp = repo->idarraydata + s->provides;
      while ((prv = *prvp++) != 0)            /* go through all provides */
	{
	  if (ISRELDEP(prv))
	    {
	      Reldep *rd = GETRELDEP(pool, prv);
	      if (rd->name == name && rd->flags == REL_EQ)
		{
		  evr = rd->evr;
		  break;
		}
	    }
	}
      if (!prv)
	continue;	/* not found in provides */
      newname = pool_tmpjoin(pool, "product:", pool_id2str(pool, prdq2.elements[i + 1]), 0);
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (name)
	{
	  /* check if we already have that product */
	  for (j = 0; j < prdq.count; j++)
	    {
	      s2 = pool->solvables + prdq.elements[j];
	      if (s2->name == name && s2->arch == s->arch && s2->evr == evr)
		break;
	    }
	  if (j < prdq.count)
	    continue;	/* yes, do not add again */
	}
      /* new product */
      if (!name)
        name = pool_str2id(pool, newname, 1);
      if (!data)
	{
	  repo_internalize(repo);	/* to make that the lookups work */
	  data = repo_add_repodata(repo, flags);
	}
      if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
	continue;		/* eek, not for installed packages, please! */
      s2 = pool_id2solvable(pool, repo_add_solvable(repo));
      s = pool->solvables + prdq2.elements[i];	/* re-calc pointer */
      s2->name = name;
      s2->arch = s->arch;
      s2->evr = evr;
      s2->vendor = s->vendor;
      /* add link requires */
      s2->requires = repo_addid_dep(repo, s2->requires, prv, 0);
      if (!autoproduct_id)
	autoproduct_id = pool_str2id(pool, "autoproduct()", 1);
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autoproduct_id, s->name, REL_EQ, 1), 0);
      /* add self provides */
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0);
      if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num);
      if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str);
      if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str);
      if ((str = solvable_lookup_str(s, SOLVABLE_DISTRIBUTION)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DISTRIBUTION, str);
      /* fill in stuff from provides */
      prvp = repo->idarraydata + s->provides;
      while ((prv = *prvp++) != 0)            /* go through all provides */
	{
	  Id evr = 0;
	  if (ISRELDEP(prv))
	    {
	      Reldep *rd = GETRELDEP(pool, prv);
	      if (rd->flags != REL_EQ)
	        continue;
	      prv = rd->name;
	      evr = rd->evr;
	    }
	  pn = pool_id2str(pool, prv);
	  if (strncmp("product-", pn, 8) != 0)
	    continue;
	  newname = 0;
	  if (evr)
	    {
	      newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
	      unescape(newname);
	    }
	  if (!strcmp(pn, "product-label()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, PRODUCT_SHORTLABEL, newname);
	  else if (!strcmp(pn, "product-type()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, PRODUCT_TYPE, newname);
	  else if (!strcmp(pn, "product-cpeid()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_CPEID, newname);
	  else if (!strcmp(pn, "product-flags()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_FLAGS, newname);
	  else if (!strcmp(pn, "product-updates-repoid()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_UPDATES_REPOID, newname);
	  else if (!strncmp(pn, "product-url(", 12) && evr && pn[12] && pn[13] && strlen(pn + 12) < 32)
	    {
	      char type[34];
	      strcpy(type, pn + 12);
	      type[strlen(type) - 1] = 0;	/* closing ) */
	      repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL_TYPE, type);
	      repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL, newname);
	    }
	}
    }
  queue_free(&prdq);
  queue_free(&prdq2);

  if (data && !(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  else if (!data && !(flags & REPO_NO_INTERNALIZE))
    repo_internalize(repo);
  return 0;
}
示例#14
0
void
request_free( Request *t )
{
  queue_free( &(t->queue) );
  free( t );
}
示例#15
0
Id
transaction_type(Transaction *trans, Id p, int mode)
{
  Pool *pool = trans->pool;
  Solvable *s = pool->solvables + p;
  Queue oq, rq;
  Id type, q;
  int i, j, ref = 0;

  if (!s->repo)
    return SOLVER_TRANSACTION_IGNORE;

  /* XXX: SUSE only? */
  if (!(mode & SOLVER_TRANSACTION_KEEP_PSEUDO) && is_noinst_pseudo_package(pool, s))
    return SOLVER_TRANSACTION_IGNORE;

  type = transaction_base_type(trans, p);

  if (type == SOLVER_TRANSACTION_IGNORE)
    return SOLVER_TRANSACTION_IGNORE;	/* not part of the transaction */

  if ((mode & SOLVER_TRANSACTION_RPM_ONLY) != 0)
    {
      /* application wants to know what to feed to the package manager */
      if (!(mode & SOLVER_TRANSACTION_KEEP_PSEUDO) && is_pseudo_package(pool, s))
	return SOLVER_TRANSACTION_IGNORE;
      if (type == SOLVER_TRANSACTION_ERASE || type == SOLVER_TRANSACTION_INSTALL || type == SOLVER_TRANSACTION_MULTIINSTALL)
	return type;
      if (s->repo == pool->installed)
	{
	  /* check if we're a real package that is obsoleted by pseudos */
	  if (!is_pseudo_package(pool, s) && obsoleted_by_pseudos_only(trans, s - pool->solvables))
	    return SOLVER_TRANSACTION_ERASE;
	  return SOLVER_TRANSACTION_IGNORE;	/* ignore as we're being obsoleted */
	}
      if (type == SOLVER_TRANSACTION_MULTIREINSTALL)
	return SOLVER_TRANSACTION_MULTIINSTALL;
      return SOLVER_TRANSACTION_INSTALL;
    }

  if ((mode & SOLVER_TRANSACTION_SHOW_MULTIINSTALL) == 0)
    {
      /* application wants to make no difference between install
       * and multiinstall */
      if (type == SOLVER_TRANSACTION_MULTIINSTALL)
        type = SOLVER_TRANSACTION_INSTALL;
      if (type == SOLVER_TRANSACTION_MULTIREINSTALL)
        type = SOLVER_TRANSACTION_REINSTALL;
    }

  if ((mode & SOLVER_TRANSACTION_CHANGE_IS_REINSTALL) != 0)
    {
      /* application wants to make no difference between change
       * and reinstall */
      if (type == SOLVER_TRANSACTION_CHANGED)
	type = SOLVER_TRANSACTION_REINSTALLED;
      else if (type == SOLVER_TRANSACTION_CHANGE)
	type = SOLVER_TRANSACTION_REINSTALL;
    }

  if (type == SOLVER_TRANSACTION_ERASE || type == SOLVER_TRANSACTION_INSTALL || type == SOLVER_TRANSACTION_MULTIINSTALL)
    return type;

  if (s->repo == pool->installed && (mode & SOLVER_TRANSACTION_SHOW_ACTIVE) == 0)
    {
      /* erase element and we're showing the passive side */
      if (type == SOLVER_TRANSACTION_OBSOLETED && (mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0)
	type = SOLVER_TRANSACTION_ERASE;
      if (type == SOLVER_TRANSACTION_OBSOLETED && (mode & SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE) != 0)
	type = SOLVER_TRANSACTION_UPGRADED;
      return type;
    }
  if (s->repo != pool->installed && (mode & SOLVER_TRANSACTION_SHOW_ACTIVE) != 0)
    {
      /* install element and we're showing the active side */
      if (type == SOLVER_TRANSACTION_OBSOLETES && (mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0)
	type = SOLVER_TRANSACTION_INSTALL;
      if (type == SOLVER_TRANSACTION_OBSOLETES && (mode & SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE) != 0)
	type = SOLVER_TRANSACTION_UPGRADE;
      return type;
    }

  /* the element doesn't match the show mode */

  /* if we're showing all references, we can ignore this package */
  if ((mode & (SOLVER_TRANSACTION_SHOW_ALL|SOLVER_TRANSACTION_SHOW_OBSOLETES)) == (SOLVER_TRANSACTION_SHOW_ALL|SOLVER_TRANSACTION_SHOW_OBSOLETES))
    return SOLVER_TRANSACTION_IGNORE;

  /* we're not showing all refs. check if some other package
   * references us. If yes, it's safe to ignore this package,
   * otherwise we need to map the type */

  /* most of the time there's only one reference, so check it first */
  q = transaction_obs_pkg(trans, p);

  if ((mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0)
    {
      Solvable *sq = pool->solvables + q;
      if (sq->name != s->name)
	{
	  /* it's a replace but we're not showing replaces. map type. */
	  if (s->repo == pool->installed)
	    return SOLVER_TRANSACTION_ERASE;
	  else if (type == SOLVER_TRANSACTION_MULTIREINSTALL)
	    return SOLVER_TRANSACTION_MULTIINSTALL;
	  else
	    return SOLVER_TRANSACTION_INSTALL;
	}
    }

  /* if there's a match, p will be shown when q
   * is processed */
  if (transaction_obs_pkg(trans, q) == p)
    return SOLVER_TRANSACTION_IGNORE;

  /* too bad, a miss. check em all */
  queue_init(&oq);
  queue_init(&rq);
  transaction_all_obs_pkgs(trans, p, &oq);
  for (i = 0; i < oq.count; i++)
    {
      q = oq.elements[i];
      if ((mode & SOLVER_TRANSACTION_SHOW_OBSOLETES) == 0)
	{
	  Solvable *sq = pool->solvables + q;
	  if (sq->name != s->name)
	    continue;
	}
      /* check if we are referenced? */
      if ((mode & SOLVER_TRANSACTION_SHOW_ALL) != 0)
	{
	  transaction_all_obs_pkgs(trans, q, &rq);
	  for (j = 0; j < rq.count; j++)
	    if (rq.elements[j] == p)
	      {
	        ref = 1;
	        break;
	      }
	  if (ref)
	    break;
	}
      else if (transaction_obs_pkg(trans, q) == p)
        {
	  ref = 1;
	  break;
        }
    }
  queue_free(&oq);
  queue_free(&rq);

  if (!ref)
    {
      /* we're not referenced. map type */
      if (s->repo == pool->installed)
	return SOLVER_TRANSACTION_ERASE;
      else if (type == SOLVER_TRANSACTION_MULTIREINSTALL)
	return SOLVER_TRANSACTION_MULTIINSTALL;
      else
	return SOLVER_TRANSACTION_INSTALL;
    }
  /* there was a ref, so p is shown with some other package */
  return SOLVER_TRANSACTION_IGNORE;
}
示例#16
0
int
pool_findfileconflicts(Pool *pool, Queue *pkgs, int cutoff, Queue *conflicts, int flags, void *(*handle_cb)(Pool *, Id, void *) , void *handle_cbdata)
{
  int i, j, cflmapn, idxmapset;
  struct cbdata cbdata;
  unsigned int now, start;
  void *handle;
  Repo *installed = pool->installed;
  Id p;
  int obsoleteusescolors = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESCOLORS);
  int hdrfetches;

  queue_empty(conflicts);
  if (!pkgs->count)
    return 0;

  now = start = solv_timems(0);
  POOL_DEBUG(SOLV_DEBUG_STATS, "searching for file conflicts\n");
  POOL_DEBUG(SOLV_DEBUG_STATS, "packages: %d, cutoff %d\n", pkgs->count, cutoff);

  memset(&cbdata, 0, sizeof(cbdata));
  cbdata.aliases = flags & FINDFILECONFLICTS_CHECK_DIRALIASING;
  cbdata.pool = pool;
  if (cbdata.aliases && (flags & FINDFILECONFLICTS_USE_ROOTDIR) != 0)
    {
      cbdata.rootdir = pool_get_rootdir(pool);
      if (cbdata.rootdir && !strcmp(cbdata.rootdir, "/"))
	cbdata.rootdir = 0;
      if (cbdata.rootdir)
	cbdata.rootdirl = strlen(cbdata.rootdir);
      if (!cbdata.rootdir)
	cbdata.usestat = 1;
    }
  queue_init(&cbdata.lookat);
  queue_init(&cbdata.lookat_dir);
  map_init(&cbdata.idxmap, pkgs->count);

  if (cutoff <= 0)
    cutoff = pkgs->count;

  /* avarage file list size: 200 files per package */
  /* avarage dir count: 20 dirs per package */

  /* first pass: scan dirs */
  if (!cbdata.aliases)
    {
      hdrfetches = 0;
      cflmapn = (cutoff + 3) * 64;
      while ((cflmapn & (cflmapn - 1)) != 0)
	cflmapn = cflmapn & (cflmapn - 1);
      cbdata.dirmap = solv_calloc(cflmapn, 2 * sizeof(Id));
      cbdata.dirmapn = cflmapn - 1;	/* make it a mask */
      cbdata.create = 1;
      idxmapset = 0;
      for (i = 0; i < pkgs->count; i++)
	{
	  if (i == cutoff)
	    cbdata.create = 0;
	  cbdata.idx = i;
	  p = pkgs->elements[i];
	  if ((flags & FINDFILECONFLICTS_USE_SOLVABLEFILELIST) != 0 && installed)
	    {
	      if (p >= installed->start && p < installed->end && pool->solvables[p].repo == installed)
		{
		  iterate_solvable_dirs(pool, p, finddirs_cb, &cbdata);
		  if (MAPTST(&cbdata.idxmap, i))
		    idxmapset++;
		  continue;
		}
	    }
	  handle = (*handle_cb)(pool, p, handle_cbdata);
	  if (!handle)
	    continue;
	  hdrfetches++;
	  rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_ONLYDIRS, finddirs_cb, &cbdata);
	  if (MAPTST(&cbdata.idxmap, i))
	    idxmapset++;
	}
      POOL_DEBUG(SOLV_DEBUG_STATS, "dirmap size: %d, used %d\n", cbdata.dirmapn + 1, cbdata.dirmapused);
      POOL_DEBUG(SOLV_DEBUG_STATS, "dirmap memory usage: %d K\n", (cbdata.dirmapn + 1) * 2 * (int)sizeof(Id) / 1024);
      POOL_DEBUG(SOLV_DEBUG_STATS, "header fetches: %d\n", hdrfetches);
      POOL_DEBUG(SOLV_DEBUG_STATS, "dirmap creation took %d ms\n", solv_timems(now));
      POOL_DEBUG(SOLV_DEBUG_STATS, "dir conflicts found: %d, idxmap %d of %d\n", cbdata.dirconflicts, idxmapset, pkgs->count);
    }

  /* second pass: scan files */
  now = solv_timems(0);
  cflmapn = (cutoff + 3) * 128;
  while ((cflmapn & (cflmapn - 1)) != 0)
    cflmapn = cflmapn & (cflmapn - 1);
  cbdata.cflmap = solv_calloc(cflmapn, 2 * sizeof(Id));
  cbdata.cflmapn = cflmapn - 1;	/* make it a mask */
  cbdata.create = 1;
  hdrfetches = 0;
  for (i = 0; i < pkgs->count; i++)
    {
      if (i == cutoff)
	cbdata.create = 0;
      if (!cbdata.aliases && !MAPTST(&cbdata.idxmap, i))
	continue;
      cbdata.idx = i;
      p = pkgs->elements[i];
      if (!cbdata.create && (flags & FINDFILECONFLICTS_USE_SOLVABLEFILELIST) != 0 && installed)
	{
	  if (p >= installed->start && p < installed->end && pool->solvables[p].repo == installed)
	    if (!precheck_solvable_files(&cbdata, pool, p))
	      continue;
	}
      /* can't use FINDFILECONFLICTS_USE_SOLVABLEFILELIST because we have to know if
       * the file is a directory or not */
      handle = (*handle_cb)(pool, p, handle_cbdata);
      if (!handle)
	continue;
      hdrfetches++;
      cbdata.lastdiridx = -1;
      rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_NOGHOSTS, cbdata.aliases ? findfileconflicts_basename_cb : findfileconflicts_cb, &cbdata);
    }

  POOL_DEBUG(SOLV_DEBUG_STATS, "filemap size: %d, used %d\n", cbdata.cflmapn + 1, cbdata.cflmapused);
  POOL_DEBUG(SOLV_DEBUG_STATS, "filemap memory usage: %d K\n", (cbdata.cflmapn + 1) * 2 * (int)sizeof(Id) / 1024);
  POOL_DEBUG(SOLV_DEBUG_STATS, "header fetches: %d\n", hdrfetches);
  POOL_DEBUG(SOLV_DEBUG_STATS, "filemap creation took %d ms\n", solv_timems(now));
  POOL_DEBUG(SOLV_DEBUG_STATS, "lookat_dir size: %d\n", cbdata.lookat_dir.count);
  queue_free(&cbdata.lookat_dir);

  /* we need another pass for aliases */
  if (cbdata.aliases)
    {
      now = solv_timems(0);
      /* make sure the first offset is not zero */
      addfilesspace(&cbdata, 1);
      cflmapn = (cutoff + 3) * 16;
      while ((cflmapn & (cflmapn - 1)) != 0)
	cflmapn = cflmapn & (cflmapn - 1);
      cbdata.normap = solv_calloc(cflmapn, 2 * sizeof(Id));
      cbdata.normapn = cflmapn - 1;	/* make it a mask */
      if (cbdata.usestat)
	{
	  cbdata.statmap = solv_calloc(cflmapn, 2 * sizeof(Id));
	  cbdata.statmapn = cflmapn - 1;	/* make it a mask */
	}
      cbdata.create = 0;
      hdrfetches = 0;
      for (i = 0; i < pkgs->count; i++)
	{
	  if (!MAPTST(&cbdata.idxmap, i))
	    continue;
	  p = pkgs->elements[i];
	  cbdata.idx = i;
	  /* can't use FINDFILECONFLICTS_USE_SOLVABLEFILELIST because we have to know if
	   * the file is a directory or not */
	  handle = (*handle_cb)(pool, p, handle_cbdata);
	  if (!handle)
	    continue;
	  hdrfetches++;
	  cbdata.lastdiridx = -1;
	  rpm_iterate_filelist(handle, RPM_ITERATE_FILELIST_NOGHOSTS, findfileconflicts_alias_cb, &cbdata);
	}
      POOL_DEBUG(SOLV_DEBUG_STATS, "normap size: %d, used %d\n", cbdata.normapn + 1, cbdata.normapused);
      POOL_DEBUG(SOLV_DEBUG_STATS, "normap memory usage: %d K\n", (cbdata.normapn + 1) * 2 * (int)sizeof(Id) / 1024);
      POOL_DEBUG(SOLV_DEBUG_STATS, "header fetches: %d\n", hdrfetches);
      POOL_DEBUG(SOLV_DEBUG_STATS, "stats made: %d\n", cbdata.statsmade);
      if (cbdata.usestat)
	{
	  POOL_DEBUG(SOLV_DEBUG_STATS, "statmap size: %d, used %d\n", cbdata.statmapn + 1, cbdata.statmapused);
	  POOL_DEBUG(SOLV_DEBUG_STATS, "statmap memory usage: %d K\n", (cbdata.statmapn + 1) * 2 * (int)sizeof(Id) / 1024);
	}
      cbdata.statmap = solv_free(cbdata.statmap);
      cbdata.statmapn = 0;
      cbdata.canonspace = solv_free(cbdata.canonspace);
      cbdata.canonspacen = 0;
      POOL_DEBUG(SOLV_DEBUG_STATS, "alias processing took %d ms\n", solv_timems(now));
    }

  cbdata.dirmap = solv_free(cbdata.dirmap);
  cbdata.dirmapn = 0;
  cbdata.dirmapused = 0;
  cbdata.cflmap = solv_free(cbdata.cflmap);
  cbdata.cflmapn = 0;
  cbdata.cflmapused = 0;

  map_free(&cbdata.idxmap);

  /* sort and unify/prune */
  now = solv_timems(0);
  POOL_DEBUG(SOLV_DEBUG_STATS, "raw candidates: %d, pruning\n", cbdata.lookat.count / 4);
  solv_sort(cbdata.lookat.elements, cbdata.lookat.count / 4, sizeof(Id) * 4, &lookat_hx_cmp, pool);
  for (i = j = 0; i < cbdata.lookat.count; )
    {
      int first = 1;
      Id hx = cbdata.lookat.elements[i];
      Id idx = cbdata.lookat.elements[i + 1];
      Id dhx = cbdata.lookat.elements[i + 2];
      Id dirid = cbdata.lookat.elements[i + 3];
      i += 4;
      for (; i < cbdata.lookat.count && hx == cbdata.lookat.elements[i] && (dirid == cbdata.lookat.elements[i + 3] || dirid == -cbdata.lookat.elements[i + 3]); i += 4)
	{
	  if (idx == cbdata.lookat.elements[i + 1] && dhx == cbdata.lookat.elements[i + 2])
	    continue;	/* ignore duplicates */
	  if (first)
	    {
	      if (dirid < 0)
		continue;	/* all have a neg dirid */
	      cbdata.lookat.elements[j++] = hx;
	      cbdata.lookat.elements[j++] = idx;
	      cbdata.lookat.elements[j++] = dhx;
	      cbdata.lookat.elements[j++] = dirid;
	      first = 0;
	    }
	  idx = cbdata.lookat.elements[i + 1];
	  dhx = cbdata.lookat.elements[i + 2];
	  cbdata.lookat.elements[j++] = hx;
	  cbdata.lookat.elements[j++] = idx;
	  cbdata.lookat.elements[j++] = dhx;
	  cbdata.lookat.elements[j++] = dirid;
	}
    }
  queue_truncate(&cbdata.lookat, j);
  POOL_DEBUG(SOLV_DEBUG_STATS, "candidates now: %d\n", cbdata.lookat.count / 4);
  POOL_DEBUG(SOLV_DEBUG_STATS, "pruning took %d ms\n", solv_timems(now));

  /* third pass: collect file info for all files that match a hx */
  now = solv_timems(0);
  solv_sort(cbdata.lookat.elements, cbdata.lookat.count / 4, sizeof(Id) * 4, &lookat_idx_cmp, pool);
  queue_init(&cbdata.files);
  hdrfetches = 0;
  for (i = 0; i < cbdata.lookat.count; i += 4)
    {
      Id idx = cbdata.lookat.elements[i + 1];
      int iterflags = RPM_ITERATE_FILELIST_WITHMD5 | RPM_ITERATE_FILELIST_NOGHOSTS;
      if (obsoleteusescolors)
	iterflags |= RPM_ITERATE_FILELIST_WITHCOL;
      p = pkgs->elements[idx];
      handle = (*handle_cb)(pool, p, handle_cbdata);
      if (handle)
	hdrfetches++;
      for (;; i += 4)
	{
	  int fstart = cbdata.files.count;
	  queue_push(&cbdata.files, idx);
	  queue_push(&cbdata.files, 0);
	  cbdata.idx = idx;
	  cbdata.hx = cbdata.lookat.elements[i];
	  cbdata.dirhash = cbdata.lookat.elements[i + 2];
	  cbdata.dirid = cbdata.lookat.elements[i + 3];
	  cbdata.lastdiridx = -1;
	  if (handle)
	    rpm_iterate_filelist(handle, iterflags, findfileconflicts2_cb, &cbdata);
	  cbdata.files.elements[fstart + 1] = cbdata.files.count;
	  cbdata.lookat.elements[i + 1] = fstart;
	  if (i + 4 >= cbdata.lookat.count || cbdata.lookat.elements[i + 4 + 1] != idx)
	    break;
	}
    }
  POOL_DEBUG(SOLV_DEBUG_STATS, "header fetches: %d\n", hdrfetches);
  POOL_DEBUG(SOLV_DEBUG_STATS, "file info fetching took %d ms\n", solv_timems(now));

  cbdata.normap = solv_free(cbdata.normap);
  cbdata.normapn = 0;

  /* forth pass: for each hx we have, compare all matching files against all other matching files */
  now = solv_timems(0);
  solv_sort(cbdata.lookat.elements, cbdata.lookat.count / 4, sizeof(Id) * 4, &lookat_hx_cmp, pool);
  for (i = 0; i < cbdata.lookat.count - 4; i += 4)
    {
      Id hx = cbdata.lookat.elements[i];
      Id pstart = cbdata.lookat.elements[i + 1];
      Id dirid = cbdata.lookat.elements[i + 3];
      Id pidx = cbdata.files.elements[pstart];
      Id pend = cbdata.files.elements[pstart + 1];
      if (cbdata.lookat.elements[i + 4] != hx)
	continue;	/* no package left with that hx */
      for (j = i + 4; j < cbdata.lookat.count && cbdata.lookat.elements[j] == hx && cbdata.lookat.elements[j + 3] == dirid; j += 4)
	{
	  Id qstart = cbdata.lookat.elements[j + 1];
	  Id qidx = cbdata.files.elements[qstart];
	  Id qend = cbdata.files.elements[qstart + 1];
	  int ii, jj;
	  if (pidx >= cutoff && qidx >= cutoff)
	    continue;	/* no conflicts between packages with idx >= cutoff */
          for (ii = pstart + 2; ii < pend; ii++)
	    for (jj = qstart + 2; jj < qend; jj++)
	      {
		char *fsi = (char *)cbdata.filesspace + cbdata.files.elements[ii];
		char *fsj = (char *)cbdata.filesspace + cbdata.files.elements[jj];
		if (cbdata.aliases)
		  {
		    /* compare just the basenames, the dirs match because of the dirid */
		    char *bsi = strrchr(fsi + 34, '/');
		    char *bsj = strrchr(fsj + 34, '/');
		    if (!bsi || !bsj)
		      continue;
		    if (strcmp(bsi, bsj))
		      continue;	/* different base names */
		  }
		else
		  {
		    if (strcmp(fsi + 34, fsj + 34))
		      continue;	/* different file names */
		  }
		if (!strcmp(fsi, fsj))
		  continue;	/* file digests match, no conflict */
		if (obsoleteusescolors && fsi[33] && fsj[33] && (fsi[33] & fsj[33]) == 0)
		  continue;	/* colors do not conflict */
		queue_push(conflicts, pool_str2id(pool, fsi + 34, 1));
		queue_push(conflicts, pkgs->elements[pidx]);
		queue_push(conflicts, pool_str2id(pool, fsi, 1));
		queue_push(conflicts, pool_str2id(pool, fsj + 34, 1));
		queue_push(conflicts, pkgs->elements[qidx]);
		queue_push(conflicts, pool_str2id(pool, fsj, 1));
	      }
	}
    }
  POOL_DEBUG(SOLV_DEBUG_STATS, "filespace size: %d K\n", cbdata.filesspacen / 1024);
  POOL_DEBUG(SOLV_DEBUG_STATS, "candidate check took %d ms\n", solv_timems(now));
  cbdata.filesspace = solv_free(cbdata.filesspace);
  cbdata.filesspacen = 0;
  queue_free(&cbdata.lookat);
  queue_free(&cbdata.files);
  if (conflicts->count > 6)
    solv_sort(conflicts->elements, conflicts->count / 6, 6 * sizeof(Id), conflicts_cmp, pool);
  POOL_DEBUG(SOLV_DEBUG_STATS, "found %d file conflicts\n", conflicts->count / 6);
  POOL_DEBUG(SOLV_DEBUG_STATS, "file conflict detection took %d ms\n", solv_timems(start));

  return conflicts->count / 6;
}
示例#17
0
文件: problems.c 项目: agraf/libsolv
static void
refine_suggestion(Solver *solv, Id *problem, Id sug, Queue *refined, int essentialok)
{
  Pool *pool = solv->pool;
  int i, j;
  Id v;
  Queue disabled;
  int disabledcnt;

  IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
    {
      POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "refine_suggestion start\n");
      for (i = 0; problem[i]; i++)
	{
	  if (problem[i] == sug)
	    POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "=> ");
	  solver_printproblem(solv, problem[i]);
	}
    }
  queue_empty(refined);
  if (!essentialok && sug < 0 && (solv->job.elements[-sug - 1] & SOLVER_ESSENTIAL) != 0)
    return;
  queue_init(&disabled);
  queue_push(refined, sug);

  /* re-enable all problem rules with the exception of "sug"(gestion) */
  solver_reset(solv);

  for (i = 0; problem[i]; i++)
    if (problem[i] != sug)
      solver_enableproblem(solv, problem[i]);

  if (sug < 0)
    solver_reenablepolicyrules(solv, -sug);
  else if (sug >= solv->updaterules && sug < solv->updaterules_end)
    {
      /* enable feature rule */
      Rule *r = solv->rules + solv->featurerules + (sug - solv->updaterules);
      if (r->p)
	solver_enablerule(solv, r);
    }

  enableweakrules(solv);

  for (;;)
    {
      int njob, nfeature, nupdate, pass;
      queue_empty(&solv->problems);
      solver_reset(solv);

      if (!solv->problems.count)
        solver_run_sat(solv, 0, 0);

      if (!solv->problems.count)
	{
	  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "no more problems!\n");
	  break;		/* great, no more problems */
	}
      disabledcnt = disabled.count;
      /* start with 1 to skip over proof index */
      njob = nfeature = nupdate = 0;
      for (pass = 0; pass < 2; pass++)
	{
	  for (i = 1; i < solv->problems.count - 1; i++)
	    {
	      /* ignore solutions in refined */
	      v = solv->problems.elements[i];
	      if (v == 0)
		break;	/* end of problem reached */
	      if (sug != v)
		{
		  /* check if v is in the given problems list
		   * we allow disabling all problem rules *after* sug in
		   * pass 2, to prevent getting the same solution twice */
		  for (j = 0; problem[j]; j++)
		    if (problem[j] == v || (pass && problem[j] == sug))
		      break;
		  if (problem[j] == v)
		    continue;
		}
	      if (v >= solv->featurerules && v < solv->featurerules_end)
		nfeature++;
	      else if (v > 0)
		nupdate++;
	      else
		{
		  if (!essentialok && (solv->job.elements[-v - 1] & SOLVER_ESSENTIAL) != 0)
		    continue;	/* not that one! */
		  njob++;
		}
	      queue_push(&disabled, v);
	    }
	  if (disabled.count != disabledcnt)
	    break;
	}
      if (disabled.count == disabledcnt)
	{
	  /* no solution found, this was an invalid suggestion! */
	  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "no solution found!\n");
	  refined->count = 0;
	  break;
	}
      if (!njob && nupdate && nfeature)
	{
	  /* got only update rules, filter out feature rules */
	  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "throwing away feature rules\n");
	  for (i = j = disabledcnt; i < disabled.count; i++)
	    {
	      v = disabled.elements[i];
	      if (v < solv->featurerules || v >= solv->featurerules_end)
	        disabled.elements[j++] = v;
	    }
	  disabled.count = j;
	  nfeature = 0;
	}
      if (disabled.count == disabledcnt + 1)
	{
	  /* just one suggestion, add it to refined list */
	  v = disabled.elements[disabledcnt];
	  if (!nfeature && v != sug)
	    queue_push(refined, v);	/* do not record feature rules */
	  solver_disableproblem(solv, v);
	  if (v >= solv->updaterules && v < solv->updaterules_end)
	    {
	      Rule *r = solv->rules + (v - solv->updaterules + solv->featurerules);
	      if (r->p)
		solver_enablerule(solv, r);	/* enable corresponding feature rule */
	    }
	  if (v < 0)
	    solver_reenablepolicyrules(solv, -v);
	}
      else
	{
	  /* more than one solution, disable all */
	  /* do not push anything on refine list, as we do not know which solution to choose */
	  /* thus, the user will get another problem if he selects this solution, where he
           * can choose the right one */
	  IF_POOLDEBUG (SOLV_DEBUG_SOLUTIONS)
	    {
	      POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "more than one solution found:\n");
	      for (i = disabledcnt; i < disabled.count; i++)
		solver_printproblem(solv, disabled.elements[i]);
	    }
	  for (i = disabledcnt; i < disabled.count; i++)
	    {
	      v = disabled.elements[i];
	      solver_disableproblem(solv, v);
	      if (v >= solv->updaterules && v < solv->updaterules_end)
		{
		  Rule *r = solv->rules + (v - solv->updaterules + solv->featurerules);
		  if (r->p)
		    solver_enablerule(solv, r);
		}
	    }
	}
    }
  /* all done, get us back into the same state as before */
  /* enable refined rules again */
  for (i = 0; i < disabled.count; i++)
    solver_enableproblem(solv, disabled.elements[i]);
  queue_free(&disabled);
  /* reset policy rules */
  for (i = 0; problem[i]; i++)
    solver_enableproblem(solv, problem[i]);
  solver_disablepolicyrules(solv);
  /* disable problem rules again */
  for (i = 0; problem[i]; i++)
    solver_disableproblem(solv, problem[i]);
  POOL_DEBUG(SOLV_DEBUG_SOLUTIONS, "refine_suggestion end\n");
}
示例#18
0
void destroy_edges(edges_list edges) {
  queue_free(edges, (free_edge_func) &destroy_edge);
}
示例#19
0
/**
* Handler to check user input, and see if it matches any avaible commands.
* Will call the right methods for executing commands
*/
void handle_keyboard(sp_session *session, struct play_queue* node)
{
    char buffer[1024];

    fgets(buffer, sizeof(buffer), stdin);
    strtok(buffer, "\n");

    if (strcmp(buffer, "search") == 0) {
        player_reset();
        run_search(session);

    } else if ((strcmp(buffer, "list") == 0) || (strcmp(buffer, "ls") == 0 )) {
        print_playlists(session, pc);

    } else if(strcmp(buffer, "qshuffle") == 0) {
        queue_shuffle();

    } else if (strcmp(buffer, "queueadd") == 0) {
        sp_playlist* pl = parse_play_command(session, buffer, node);
        printf("done finding playlist \n");

        if(pl != NULL) printf("queueadd: %s\n", sp_playlist_name(pl));
        else {
            printf("no playlist\n");
            return;
        }

        int index;
        char input[10];
        fputs("Song number: ", stdout);
        fgets(input, sizeof(input) - 1, stdin);
        sscanf(input, "%d", &index);
        if(sp_playlist_num_tracks(pl) < index) {
            printf("index too high!\n");
            return;
        }

        sp_track* track = pl_find_song_by_id(pl, index);
        if(track != NULL) queue_add_first(track);

    } else if (strcmp(buffer, "list songs") == 0 ) {
        //release all threads
        sp_playlist* pl = playlist_find_by_num(session, pc);
        print_tracks_in_playlist(session, pl);

    } else if (strcmp(buffer, "help") == 0) {
        print_commands();

    } else if (strcmp(buffer, "queue") == 0) {
        queue_print(node);

    } else if (strcmp(buffer, "shuffle mode") == 0) {
        print_commands();

    } else if(strncmp(buffer, "play", strlen("play")) == 0) {
        player_reset();
        sp_playlist* pl = parse_play_command(session, buffer, node);
        if(pl!=NULL) queue_add_playlist(pl);
        else {
            printf("ERROR playlist is null\n");
            return;
        }
        queue_go_next(session);


    } else if(strncmp(buffer, "shuffle", strlen("shuffle")) == 0) {
        player_reset();
        shuffle_mode = TRUE;
        sp_playlist* pl = parse_play_command(session, buffer, node);
        if(pl!=NULL) queue_add_playlist(pl);
        else {
            printf("ERROR playlist is null\n");
            return;
        }
        queue_shuffle();
        queue_go_next(session);

    } else if(strcmp(buffer, "pause") == 0 || strcmp(buffer, "p") == 0) {
        player_pause(session);
        play_info();

    } else if (strcmp(buffer, "next") == 0 || strcmp(buffer, "n") == 0) {
        end_track(session);

    } else if (strcmp(buffer, "stop") == 0) {

    } else if (strcmp(buffer, "info") == 0) {
        play_info();
    } else if (strcmp(buffer, "quit") == 0) {
        queue_free();
        quit_program(session);
    } else {
        printf("Unkown command!\n");
    }
    printf("> ");
    fflush(stdout);

    return;
}
示例#20
0
void
repo_set_deparray(Repo *repo, Id p, Id keyname, Queue *q, Id marker)
{
  Repodata *data;
  if (marker)
    {
      /* complex case, splice old and new arrays */
      int i;
      Queue q2;
      queue_init(&q2);
      repo_lookup_deparray(repo, p, keyname, &q2, -marker);
      if (marker > 0)
	{
	  if (q->count)
	    {
	      queue_push(&q2, marker);
	      for (i = 0; i < q->count; i++)
		queue_push(&q2, q->elements[i]);
	    }
	}
      else
	{
	  if (q2.count)
	    queue_insert(&q2, 0, -marker);
	  queue_insertn(&q2, 0, q->count);
	  for (i = 0; i < q->count; i++)
	   q2.elements[i] = q->elements[i];
	}
      repo_set_deparray(repo, p, keyname, &q2, 0);
      queue_free(&q2);
      return;
    }
  if (p >= 0)
    {
      Solvable *s = repo->pool->solvables + p;
      switch (keyname)
	{
	case SOLVABLE_PROVIDES:
	  s->provides = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_OBSOLETES:
	  s->obsoletes = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_CONFLICTS:
	  s->conflicts = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_REQUIRES:
	  s->requires = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_RECOMMENDS:
	  s->recommends = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_SUGGESTS:
	  s->suggests = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_SUPPLEMENTS:
	  s->supplements = repo_set_idarray_solvable(repo, q);
	  return;
	case SOLVABLE_ENHANCES:
	  s->enhances = repo_set_idarray_solvable(repo, q);
	  return;
	}
    }
  data = repo_last_repodata(repo);
  repodata_set_idarray(data, p, keyname, q);
}
示例#21
0
/* Initiate the communication with a remote site. When communication is
 * established create a minisocket through which the communication can be made
 * from now on.
 *
 * The first argument is the network address of the remote machine. 
 *
 * The argument "port" is the port number on the remote machine to which the
 * connection is made. The port number of the local machine is one of the free
 * port numbers.
 *
 * Return value: the minisocket_t created, otherwise NULL with the errorcode
 * stored in the "error" variable.
 */
minisocket_t minisocket_client_create(network_address_t addr, int port, minisocket_error *error)
{
  minisocket_t new_sock;
  interrupt_level_t l;
  resend_arg* resend_alarm_arg;
  unsigned short start; 
  char tmp;

  //check valid portnum
  if (port < 0 || port >= CLIENT_START) {
    *error = SOCKET_INVALIDPARAMS;
    return NULL;
  }

  semaphore_P(client_lock);
  start = curr_client_idx;
  while (sock_array[curr_client_idx] != NULL){
    curr_client_idx++;
    if (curr_client_idx >= NUM_SOCKETS){
      curr_client_idx = CLIENT_START;
    }
    if (curr_client_idx == start){ // client sockets full
      semaphore_V(client_lock);
      *error = SOCKET_NOMOREPORTS; 
      return NULL;
    }
  }
 
  new_sock = (minisocket_t)malloc(sizeof(struct minisocket));
  if (!new_sock){
    semaphore_V(client_lock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->pkt_ready_sem = semaphore_create();
  if (!(new_sock->pkt_ready_sem)){
    semaphore_V(client_lock);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->pkt_q = queue_new();
  if (!(new_sock->pkt_q)){
    semaphore_V(client_lock);
    semaphore_destroy(new_sock->pkt_ready_sem);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->sock_lock = semaphore_create();
  if (!(new_sock->sock_lock)){
    semaphore_V(client_lock);
    semaphore_destroy(new_sock->pkt_ready_sem);
    queue_free(new_sock->pkt_q);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  new_sock->ack_ready_sem = semaphore_create();
  if (!(new_sock->ack_ready_sem)){
    semaphore_V(client_lock);
    semaphore_destroy(new_sock->pkt_ready_sem);
    queue_free(new_sock->pkt_q);
    semaphore_destroy(new_sock->sock_lock);
    free(new_sock);
    *error = SOCKET_OUTOFMEMORY;
    return NULL;
  }
  
  semaphore_initialize(new_sock->pkt_ready_sem, 0);
  semaphore_initialize(new_sock->ack_ready_sem, 0);
  semaphore_initialize(new_sock->sock_lock, 1);

  new_sock->curr_state = CONNECT_WAIT;
  new_sock->try_count = 0;
  new_sock->curr_ack = 0;
  new_sock->curr_seq = 1;
  new_sock->resend_alarm = NULL; //no alarm set
  new_sock->src_port = curr_client_idx;
  new_sock->dst_port = port; 
  network_address_copy(addr, new_sock->dst_addr);

  sock_array[curr_client_idx] = new_sock;
  semaphore_V(client_lock);
 
  l = set_interrupt_level(DISABLED);
  minisocket_send_ctrl(MSG_SYN, new_sock, error);
  resend_alarm_arg = (resend_arg*)calloc(1, sizeof(resend_arg));
  resend_alarm_arg->sock = new_sock;
  resend_alarm_arg->msg_type = MSG_SYN;
  resend_alarm_arg->data_len = 0;
  resend_alarm_arg->data = &tmp; //placeholder
  resend_alarm_arg->error = error; 
  new_sock->resend_alarm = set_alarm(RESEND_TIME_UNIT, minisocket_resend, resend_alarm_arg, minithread_time());
  set_interrupt_level(l);

  semaphore_P(new_sock->ack_ready_sem);
  l = set_interrupt_level(DISABLED);

  switch(new_sock->curr_state) {
  case CONNECTED: //we are connected
    // must have gotten a MSG_SYNACK
    new_sock->curr_state = CONNECTED;
    new_sock->try_count = 0;
    if (new_sock->resend_alarm){
      deregister_alarm(new_sock->resend_alarm);
    }
    new_sock->resend_alarm = NULL;
    *error = SOCKET_NOERROR;
    set_interrupt_level(l); 
    break;
  
  case CLOSE_RCV:
    *error = SOCKET_BUSY;
    minisocket_destroy(new_sock, error);
    if (new_sock->resend_alarm){
      deregister_alarm(new_sock->resend_alarm);
    }
    new_sock->resend_alarm = NULL;
    *error = SOCKET_BUSY;
    set_interrupt_level(l);
    new_sock = NULL;
    break; 
  
  default:
    // error
    *error = SOCKET_NOSERVER;
    minisocket_destroy(new_sock, error);
    set_interrupt_level(l); 
    new_sock = NULL;
    break;
  }
  free(resend_alarm_arg);
  return new_sock;
}
示例#22
0
static void test_queue (void) {
  Queue* queue;

  queue = queue_new();
  queue_free (queue);
  }
示例#23
0
int
repo_add_autopattern(Repo *repo, int flags)
{
  Pool *pool = repo->pool;
  Repodata *data = 0;
  Solvable *s, *s2;
  Queue q, q2;
  Id p;
  Id pattern_id;
  Id autopattern_id = 0;
  int i, j;

  queue_init(&q);
  queue_init(&q2);

  pattern_id = pool_str2id(pool, "pattern()", 9);
  FOR_REPO_SOLVABLES(repo, p, s)
    {
      const char *n = pool_id2str(pool, s->name);
      if (!strncmp("pattern:", n, 8))
	queue_push(&q, p);
      else if (s->provides)
	{
	  Id prv, *prvp = repo->idarraydata + s->provides;
	  while ((prv = *prvp++) != 0)            /* go through all provides */
	    if (ISRELDEP(prv))
	      {
	        Reldep *rd = GETRELDEP(pool, prv);
		if (rd->name == pattern_id && rd->flags == REL_EQ)
		  {
		    queue_push2(&q2, p, rd->evr);
		    break;
		  }
	      }
	}
    }
  for (i = 0; i < q2.count; i += 2)
    {
      const char *pn = 0;
      char *newname;
      Id name, prv, *prvp;
      const char *str;
      unsigned long long num;

      s = pool->solvables + q2.elements[i];
      /* construct new name */
      newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, q2.elements[i + 1]), 0);
      unescape(newname);
      name = pool_str2id(pool, newname, 0);
      if (name)
	{
	  /* check if we already have that pattern */
	  for (j = 0; j < q.count; j++)
	    {
	      s2 = pool->solvables + q.elements[j];
	      if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr)
		break;
	    }
	  if (j < q.count)
	    continue;	/* yes, do not add again */
	}
      /* new pattern */
      if (!name)
        name = pool_str2id(pool, newname, 1);
      if (!data)
	{
	  repo_internalize(repo);	/* to make that the lookups work */
	  data = repo_add_repodata(repo, flags);
	}
      s2 = pool_id2solvable(pool, repo_add_solvable(repo));
      s = pool->solvables + q2.elements[i];	/* re-calc pointer */
      s2->name = name;
      s2->arch = s->arch;
      s2->evr = s->evr;
      s2->vendor = s->vendor;
      /* add link requires */
      s2->requires = repo_addid_dep(repo, s2->requires, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1) , 0);
      /* add autopattern provides */
      if (!autopattern_id)
	autopattern_id = pool_str2id(pool, "autopattern()", 1);
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autopattern_id, s->name, REL_EQ, 1), 0);
      /* add self provides */
      s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0);
      if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_INSTALLTIME, num);
      if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0)
	repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num);
      if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str);
      if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0)
	repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str);
      /* fill in stuff from provides */
      prvp = repo->idarraydata + s->provides;
      while ((prv = *prvp++) != 0)            /* go through all provides */
	{
	  Id evr = 0;
	  if (ISRELDEP(prv))
	    {
	      Reldep *rd = GETRELDEP(pool, prv);
	      if (rd->flags != REL_EQ)
	        continue;
	      prv = rd->name;
	      evr = rd->evr;
	    }
	  pn = pool_id2str(pool, prv);
	  if (strncmp("pattern-", pn, 8) != 0)
	    continue;
	  newname = 0;
	  if (evr)
	    {
	      newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0);
	      unescape(newname);
	    }
	  if (!strncmp(pn, "pattern-category(", 17) && evr)
	    {
	      char lang[9];
	      int l = strlen(pn);
	      Id langtag;
	      if (l > 17 + 9 || pn[l - 1] != ')')
		continue;
              strncpy(lang, pn + 17, l - 17 - 1);
	      lang[l - 17 - 1] = 0;
	      langtag = SOLVABLE_CATEGORY;
	      if (*lang && strcmp(lang, "en") != 0)
		langtag = pool_id2langid(pool, SOLVABLE_CATEGORY, lang, 1);
	      repodata_set_str(data, s2 - pool->solvables, langtag, newname);
	    }
	  else if (!strcmp(pn, "pattern-includes()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_INCLUDES, pool_tmpjoin(pool, "pattern:", newname, 0));
	  else if (!strcmp(pn, "pattern-extends()") && evr)
	    repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_EXTENDS, pool_tmpjoin(pool, "pattern:", newname, 0));
	  else if (!strcmp(pn, "pattern-icon()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ICON, newname);
	  else if (!strcmp(pn, "pattern-order()") && evr)
	    repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ORDER, newname);
	  else if (!strcmp(pn, "pattern-visible()") && !evr)
	    repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE);
	}
    }
  queue_free(&q);
  queue_free(&q2);
  if (data && !(flags & REPO_NO_INTERNALIZE))
    repodata_internalize(data);
  else if (!data && !(flags & REPO_NO_INTERNALIZE))
    repo_internalize(repo);
  return 0;
}
示例#24
0
int ark_create_verbose(char *path, ARK **arkret,
                       uint64_t size, uint64_t bsize, uint64_t hcount,
                       int nthrds, int nqueue, int basyncs, uint64_t flags)
{
  int          rc = 0;
  int        p_rc = 0;
  uint64_t bcount = 0;
  uint64_t      x = 0;
  int           i = 0;
  int        tnum = 0;
  int        rnum = 0;
  scb_t     *scbp = NULL;

  KV_TRC_OPEN(pAT, "arkdb");

  if (NULL == arkret)
  {
    KV_TRC_FFDC(pAT, "Incorrect value for ARK control block: rc=EINVAL");
    rc = EINVAL;
    goto ark_create_ark_err;
  }

  if ( (flags & (ARK_KV_PERSIST_LOAD|ARK_KV_PERSIST_STORE)) && 
         (flags & ARK_KV_VIRTUAL_LUN) )
  {
    KV_TRC_FFDC(pAT, "Invalid persistence combination with ARK flags: %016lx",
                flags);
    rc = EINVAL;
    goto ark_create_ark_err;
  }

  if (nthrds <= 0)
  {
      KV_TRC_FFDC(pAT, "invalid nthrds:%d", nthrds);
      rc = EINVAL;
      goto ark_create_ark_err;
  }

  _ARK *ark = am_malloc(sizeof(_ARK));
  if (ark == NULL) {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocating ARK control structure for %ld",
                sizeof(_ARK));
    goto ark_create_ark_err;
  }

  KV_TRC(pAT, "%p path(%s) size %ld bsize %ld hcount %ld "
              "nthrds %d nqueue %d basyncs %d flags:%08lx",
              ark, path, size, bsize, hcount, 
              nthrds, nqueue, basyncs, flags);

  ark->bsize    = bsize;
  ark->rthread  = 0;
  ark->persload = 0;
  ark->nasyncs  = ((nqueue <= 0) ? ARK_MAX_ASYNC_OPS : nqueue);
  ark->basyncs  = basyncs;
  ark->ntasks   = ARK_MAX_TASK_OPS;
  ark->nthrds   = ARK_VERBOSE_NTHRDS_DEF; // hardcode, perf requirement

  // Create the KV storage, whether that will be memory based
  // or flash
  ark->ea = ea_new(path, ark->bsize, basyncs, &size, &bcount,
                    (flags & ARK_KV_VIRTUAL_LUN));
  if (ark->ea == NULL)
  {
    if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
    rc = errno;
    KV_TRC_FFDC(pAT, "KV storage initialization failed: rc/errno:%d", rc);
    goto ark_create_ea_err;
  }

  // Now that the "connection" to the store has been established
  // we need to check to see if data was persisted from a previous
  // instantiation of the KV store.
  p_rc = ark_check_persistence(ark, flags);
  if (p_rc > 0)
  {
    // We ran into an error while trying to read from
    // the store.
    rc = p_rc;
    KV_TRC_FFDC(pAT, "Persistence check failed: %d", rc);
    goto ark_create_persist_err;
  }
  else if (p_rc == -1)
  {
    KV_TRC(pAT, "NO PERSIST LOAD FLAG");
    // There was no persistence data, so we just build off
    // of what was passed into the API.

    ark->size = size;
    ark->bcount = bcount;
    ark->hcount = hcount;
    ark->vlimit = ARK_VERBOSE_VLIMIT_DEF;
    ark->blkbits = ARK_VERBOSE_BLKBITS_DEF;
    ark->grow = ARK_VERBOSE_GROW_DEF;
    ark->rthread = 0;
    ark->flags = flags;
    ark->astart = 0;
    ark->blkused = 1;
    ark->ark_exit = 0;
    ark->nactive = 0;
    ark->pers_stats.kv_cnt = 0;
    ark->pers_stats.blk_cnt = 0;
    ark->pers_stats.byte_cnt = 0;
    ark->pcmd = PT_IDLE;

    // Create the requests and tag control blocks and queues.
    x = ark->hcount / ark->nthrds;
    ark->npart  = x + (ark->hcount % ark->nthrds ? 1 : 0);

    // Create the hash table
    ark->ht = hash_new(ark->hcount);
    if (ark->ht == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Hash initialization failed: %d", rc);
      goto ark_create_ht_err;
    }

    // Create the block list
    ark->bl = bl_new(ark->bcount, ark->blkbits);
    if (ark->bl == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Block list initialization failed: %d", rc);
      goto ark_create_bl_err;
    }
    if (flags & ARK_KV_PERSIST_STORE)
    {
      ark_persistence_calc(ark);
      if (bl_reserve(ark->bl, ark->pers_max_blocks))
          {goto ark_create_bl_err;}
    }
  }
  else
  {
      KV_TRC(pAT, "PERSIST: %p path(%s) size %ld bsize %ld hcount %ld "
                  "nthrds %d nqueue %ld basyncs %d bcount %ld blkbits %ld",
                  ark, path, ark->size, ark->bsize, ark->hcount,
                  ark->nthrds, ark->nasyncs, ark->basyncs,
                  ark->bcount, ark->blkbits);
  }

  rc = pthread_mutex_init(&ark->mainmutex,NULL);
  if (rc != 0)
  {
    KV_TRC_FFDC(pAT, "pthread_mutex_init for main mutex failed: %d", rc);
    goto ark_create_pth_mutex_err;
  }

  ark->rtags = tag_new(ark->nasyncs);
  if ( NULL == ark->rtags )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Tag initialization for requests failed: %d", rc);
    goto ark_create_rtag_err;
  }

  ark->ttags = tag_new(ark->ntasks);
  if ( NULL == ark->ttags )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Tag initialization for tasks failed: %d", rc);
    goto ark_create_ttag_err;
  }

  ark->rcbs = am_malloc(ark->nasyncs * sizeof(rcb_t));
  if ( NULL == ark->rcbs )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for request control blocks", (ark->nasyncs * sizeof(rcb_t)));
    goto ark_create_rcbs_err;
  }

  ark->tcbs = am_malloc(ark->ntasks * sizeof(tcb_t));
  if ( NULL == ark->tcbs )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for task control blocks", (ark->ntasks * sizeof(rcb_t)));
    goto ark_create_tcbs_err;
  }

  ark->iocbs = am_malloc(ark->ntasks * sizeof(iocb_t));
  if ( NULL == ark->iocbs )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for io control blocks", (ark->ntasks * sizeof(iocb_t)));
    goto ark_create_iocbs_err;
  }

  ark->poolthreads = am_malloc(ark->nthrds * sizeof(scb_t));
  if ( NULL == ark->poolthreads )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for server thread control blocks", (ark->nthrds * sizeof(scb_t)));
    goto ark_create_poolthreads_err;
  }

  for ( rnum = 0; rnum < ark->nasyncs ; rnum++ )
  {
    ark->rcbs[rnum].stat = A_NULL;
    pthread_cond_init(&(ark->rcbs[rnum].acond), NULL);
    pthread_mutex_init(&(ark->rcbs[rnum].alock), NULL);
  }

  for ( tnum = 0; tnum < ark->ntasks; tnum++ )
  {
    ark->tcbs[tnum].inb = bt_new(0, ark->vlimit, sizeof(uint64_t), 
                                       &(ark->tcbs[tnum].inblen),
                                       &(ark->tcbs[tnum].inb_orig));
    if (ark->tcbs[tnum].inb == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Bucket allocation for inbuffer failed: %d", rc);
      goto ark_create_taskloop_err;
    }

    ark->tcbs[tnum].oub = bt_new(0, ark->vlimit, sizeof(uint64_t), 
                                       &(ark->tcbs[tnum].oublen),
                                       &(ark->tcbs[tnum].oub_orig));
    if (ark->tcbs[tnum].oub == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Bucket allocation for outbuffer failed: %d", rc);
      goto ark_create_taskloop_err;
    }

    //ark->tcbs[tnum].vbsize = bsize * 1024;
    ark->tcbs[tnum].vbsize = bsize * 256;
    ark->tcbs[tnum].vb_orig = am_malloc(ark->tcbs[tnum].vbsize);
    if (ark->tcbs[tnum].vb_orig == NULL)
    {
      rc = ENOMEM;
      KV_TRC_FFDC(pAT, "Out of memory allocation for %"PRIu64" bytes for variable size buffer", (bsize * 1024));
      goto ark_create_taskloop_err;
    }
    ark->tcbs[tnum].vb = ptr_align(ark->tcbs[tnum].vb_orig);
  }

  *arkret = (void *)ark;

  ark->pts = (PT *)am_malloc(sizeof(PT) * ark->nthrds);
  if ( ark->pts == NULL )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation for %"PRIu64" bytes for server thread data", (sizeof(PT) * ark->nthrds));
    goto ark_create_taskloop_err;
  }

  for (i = 0; i < ark->nthrds; i++) {
    PT *pt = &(ark->pts[i]);
    scbp = &(ark->poolthreads[i]);

    memset(scbp, 0, sizeof(scb_t));

    // Start off the random start point for this thread
    // at -1, to show that it has not been part of a
    // ark_random call.
    scbp->rlast = -1;
    scbp->holds = 0;
    scbp->poolstate = PT_RUN;

    scbp->poolstats.io_cnt = 0;
    scbp->poolstats.ops_cnt = 0;
    scbp->poolstats.kv_cnt = 0;
    scbp->poolstats.blk_cnt = 0;
    scbp->poolstats.byte_cnt = 0;

    pthread_mutex_init(&(scbp->poolmutex), NULL);
    pthread_cond_init(&(scbp->poolcond), NULL);

    scbp->rqueue = queue_new(ark->nasyncs);
    scbp->tqueue = queue_new(ark->ntasks);
    scbp->ioqueue = queue_new(ark->ntasks);

    pt->id = i;
    pt->ark = ark;
    rc = pthread_create(&(scbp->pooltid), NULL, pool_function, pt);
    if (rc != 0)
    {
      KV_TRC_FFDC(pAT, "pthread_create of server thread failed: %d", rc);
      goto ark_create_poolloop_err;
    }
  }

#if 0
  while (ark->nactive < ark->nthrds) {
    usleep(1);
    //printf("Create waiting %d/%d\n", ark->nactive, ark->nthrds);
  }
#endif

  ark->pcmd = PT_RUN;

  goto ark_create_return;

ark_create_poolloop_err:

  for (; i >= 0; i--)
  {
    scbp = &(ark->poolthreads[i]);

    if (scbp->pooltid != 0)
    {
      queue_lock(scbp->rqueue);
      queue_wakeup(scbp->rqueue);
      queue_unlock(scbp->rqueue);
      pthread_join(scbp->pooltid, NULL);

      pthread_mutex_destroy(&(scbp->poolmutex));
      pthread_cond_destroy(&(scbp->poolcond));

      if ( scbp->rqueue != NULL )
      {
        queue_free(scbp->rqueue);
      }

      if ( scbp->tqueue != NULL )
      {
        queue_free(scbp->tqueue);
      }
    
      if ( scbp->ioqueue != NULL )
      {
        queue_free(scbp->ioqueue);
      }
    }
  }

  if ( ark->pts != NULL )
  {
    am_free(ark->pts);
  }

ark_create_taskloop_err:
  for ( tnum = 0; tnum < ark->ntasks; tnum++ )
  {
    if (ark->tcbs[tnum].inb)
    {
      bt_delete(ark->tcbs[tnum].inb);
    }

    if (ark->tcbs[tnum].oub)
    {
      bt_delete(ark->tcbs[tnum].oub);
    }

    if (ark->tcbs[tnum].vb_orig)
    {
      am_free(ark->tcbs[tnum].vb_orig);
    }
  }

  for (rnum = 0; rnum < ark->nasyncs; rnum++)
  {
    pthread_cond_destroy(&(ark->rcbs[rnum].acond));
    pthread_mutex_destroy(&(ark->rcbs[rnum].alock));
  }

  if ( ark->poolthreads != NULL )
  {
    am_free(ark->poolthreads);
  }

ark_create_poolthreads_err:
  if (ark->iocbs)
  {
    am_free(ark->iocbs);
  }

ark_create_iocbs_err:
  if (ark->tcbs)
  {
    am_free(ark->tcbs);
  }

ark_create_tcbs_err:
  if (ark->rcbs)
  {
    am_free(ark->rcbs);
  }

ark_create_rcbs_err:
  if (ark->ttags)
  {
    tag_free(ark->ttags);
  }

ark_create_ttag_err:
  if (ark->rtags)
  {
    tag_free(ark->rtags);
  }

ark_create_rtag_err:
  pthread_mutex_destroy(&ark->mainmutex);

ark_create_pth_mutex_err:
  bl_delete(ark->bl);

ark_create_bl_err:
  hash_free(ark->ht);

ark_create_ht_err:
ark_create_persist_err:
  ea_delete(ark->ea);

ark_create_ea_err:
  am_free(ark);
  *arkret = NULL;

ark_create_ark_err:
  KV_TRC_CLOSE(pAT);

ark_create_return:
  return rc;
}
示例#25
0
int main(int argc, char *argv[])
{
    int studentsCount = -1;

    // parse the number of students
    printf("Please enter the number of students: ");
    scanf("%d", &studentsCount);
    if (studentsCount <= 0)
    {
        printf("Not a valid number; aborting.\n");
        return 1;
    }
    
    // we need to initialize the students' array
    students = (student*) malloc(sizeof (student) * studentsCount);

    // set a seed for the random number generator
    rand_ts_initialize(&rSeed, time(NULL));

    // the wakeup signal, to wake up the TA
    sig_initialize(&wakeupSignal);
    sem_init(&taHelping, 0, 0);

    // initialize the queue
    queue_init(&chairsQueue, AVAILABLE_CHAIRS);

    // the threads that are going to be used
    pthread_t* student_threads = (pthread_t*) malloc(sizeof (pthread_t) * studentsCount);
    pthread_t ta_thread;

    int i;

    // initialize the chairs' semaphores
    for (i = 0; i < AVAILABLE_CHAIRS; ++i)
        sem_init(&chairs_sems[i], 0, 0);

    // create the TA thread before the student threads
    pthread_create(&ta_thread, 0, &taFn, NULL);

    // students threads
    for (i = 0; i < studentsCount; ++i)
    {
        student* s = &students[i];
        s->id = (i + 1);
        s->waitSem = NULL;

        // create the student thread, and pass the student struct as a pointer.
        pthread_create(&student_threads[i], 0, &studentFn, s);
    }

    // wait for the threads to end. a.k.a never.
    for (i = 0; i < studentsCount; ++i)
        pthread_join(student_threads[i], NULL);
    pthread_join(ta_thread, NULL);

    // cleanup resources
    for (i = 0; i < AVAILABLE_CHAIRS; ++i)
        sem_destroy(&chairs_sems[i]);

    rand_ts_destroy(&rSeed);
    free(students);
    free(student_threads);
    queue_free(&chairsQueue);
    sig_destroy(&wakeupSignal);
    sem_destroy(&taHelping);

    return 0;
}
示例#26
0
int ark_delete(ARK *ark) {
  int rc = 0;
  int i = 0;
  _ARK *_arkp = (_ARK *)ark;
  scb_t *scbp = NULL;

  if (NULL == ark)
  {
    rc = EINVAL;
    KV_TRC_FFDC(pAT, "Invalid ARK control block parameter: %d", rc);
    goto ark_delete_ark_err;
  }

  // Wait for all active threads to exit
  for (i = 0; i < _arkp->nthrds; i++)
  {
      scbp = &(_arkp->poolthreads[i]);
      scbp->poolstate = PT_EXIT;

      queue_lock(scbp->rqueue);
      queue_wakeup(scbp->rqueue);
      queue_unlock(scbp->rqueue);

      pthread_join(scbp->pooltid, NULL);

      queue_free(scbp->rqueue);
      queue_free(scbp->tqueue);
      queue_free(scbp->ioqueue);

      pthread_mutex_destroy(&(scbp->poolmutex));
      pthread_cond_destroy(&(scbp->poolcond));
      KV_TRC(pAT, "thread %d joined", i);
  }

  if (_arkp->poolthreads) am_free(_arkp->poolthreads);

  if (_arkp->pts) am_free(_arkp->pts);

  for ( i = 0; i < _arkp->nasyncs ; i++ )
  {
    pthread_cond_destroy(&(_arkp->rcbs[i].acond));
    pthread_mutex_destroy(&(_arkp->rcbs[i].alock));
  }

  for ( i = 0; i < _arkp->ntasks; i++ )
  {

    bt_delete(_arkp->tcbs[i].inb);
    bt_delete(_arkp->tcbs[i].oub);
    am_free(_arkp->tcbs[i].vb_orig);
  }

  if (_arkp->iocbs)
  {
    am_free(_arkp->iocbs);
  }

  if (_arkp->tcbs)
  {
    am_free(_arkp->tcbs);
  }

  if (_arkp->rcbs)
  {
    am_free(_arkp->rcbs);
  }

  if (_arkp->ttags)
  {
    tag_free(_arkp->ttags);
  }

  if (_arkp->rtags)
  {
    tag_free(_arkp->rtags);
  }

  if (!(_arkp->flags & ARK_KV_VIRTUAL_LUN))
  {
    rc = ark_persist(_arkp);
    if ( rc != 0 )
    {
      KV_TRC_FFDC(pAT, "FFDC: ark_persist failed: %d", rc);
    }
  }

  pthread_mutex_destroy(&_arkp->mainmutex);

  (void)ea_delete(_arkp->ea);
  hash_free(_arkp->ht);
  bl_delete(_arkp->bl);
  KV_TRC(pAT, "ark_delete done %p", _arkp);
  am_free(_arkp);

ark_delete_ark_err:
  KV_TRC_CLOSE(pAT);
  return rc;
}
示例#27
0
static void
repo_addfileprovides_search(Repo *repo, struct addfileprovides_cbdata *cbd, struct searchfiles *sf)
{
  Repodata *data;
  int rdid, p, i;
  int provstart, provend;
  Map todo;
  Map providedids;

  if (repo->end <= repo->start || !repo->nsolvables || !sf->nfiles)
    return;

  /* update search data if changed */
  if (cbd->nfiles != sf->nfiles || cbd->ids != sf->ids)
    {
      free_dirs_names_array(cbd);
      cbd->nfiles = sf->nfiles;
      cbd->ids = sf->ids;
      cbd->dids = solv_realloc2(cbd->dids, sf->nfiles, sizeof(Id));
    }

  /* create todo map and range */
  map_init(&todo, repo->end - repo->start);
  for (p = repo->start; p < repo->end; p++)
    if (repo->pool->solvables[p].repo == repo)
      MAPSET(&todo, p - repo->start);
  cbd->todo = &todo;
  cbd->todo_start = repo->start;
  cbd->todo_end = repo->end;
  prune_todo_range(repo, cbd);

  provstart = provend = 0;
  map_init(&providedids, 0);
  data = repo_lookup_repodata(repo, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES);
  if (data)
    {
      Queue fileprovidesq;
      queue_init(&fileprovidesq);
      if (repodata_lookup_idarray(data, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &fileprovidesq))
	{
	  map_grow(&providedids, repo->pool->ss.nstrings);
	  cbd->providedids = &providedids;
	  provstart = data->start;
	  provend = data->end;
	  for (i = 0; i < fileprovidesq.count; i++)
	    MAPSET(&providedids, fileprovidesq.elements[i]);
	  for (i = 0; i < cbd->nfiles; i++)
	    if (!MAPTST(&providedids, cbd->ids[i]))
	      break;
	  if (i == cbd->nfiles)
	    {
	      /* all included, clear entries from todo list */
	      if (provstart <= cbd->todo_start && provend >= cbd->todo_end)
		cbd->todo_end = cbd->todo_start;	/* clear complete range */
	      else
		{
		  for (p = provstart; p < provend; p++)
		    MAPCLR(&todo, p - repo->start);
		  prune_todo_range(repo, cbd);
		}
	    }
	}
      queue_free(&fileprovidesq);
    }

  if (cbd->todo_start >= cbd->todo_end)
    {
      map_free(&todo);
      cbd->todo = 0;
      map_free(&providedids);
      cbd->providedids = 0;
      return;
    }

  /* this is similar to repo_lookup_filelist_repodata in repo.c */

  for (rdid = 1, data = repo->repodata + rdid; rdid < repo->nrepodata; rdid++, data++)
    if (data->filelisttype == REPODATA_FILELIST_FILTERED)
      break;
  for (; rdid < repo->nrepodata; rdid++, data++)
    if (data->filelisttype == REPODATA_FILELIST_EXTENSION)
      break;

  if (rdid < repo->nrepodata)
    {
      /* have at least one repodata with REPODATA_FILELIST_FILTERED followed by REPODATA_FILELIST_EXTENSION */
      Map postpone;
      map_init(&postpone, 0);
      for (rdid = repo->nrepodata - 1, data = repo->repodata + rdid; rdid > 0; rdid--, data--)
	{
	  if (data->filelisttype != REPODATA_FILELIST_FILTERED)
	    continue;
	  if (!repodata_intersects_todo(data, cbd))
	    continue;
	  if (data->state != REPODATA_AVAILABLE)
	    {
	      if (data->state != REPODATA_STUB)
		continue;
	      repodata_load(data);
	      if (data->state != REPODATA_AVAILABLE || data->filelisttype != REPODATA_FILELIST_FILTERED)
		continue;
	    }
	  repo_addfileprovides_search_filtered(repo, cbd, rdid, &postpone);
	}
      if (postpone.size)
	{
	  /* add postponed entries back to todo */
	  map_or(&todo, &postpone);
	  cbd->todo_start = repo->start;
	  cbd->todo_end = repo->end;
	  prune_todo_range(repo, cbd);
	}
      map_free(&postpone);
    }

  /* search remaining entries in the standard way */
  if (cbd->todo_start < cbd->todo_end)
    {
      for (rdid = repo->nrepodata - 1, data = repo->repodata + rdid; rdid > 0; rdid--, data--)
	{
	  if (data->start >= cbd->todo_end || data->end <= cbd->todo_start)
	    continue;
	  if (!repodata_has_keyname(data, SOLVABLE_FILELIST))
	    continue;
	  if (!repodata_intersects_todo(data, cbd))
	    continue;
	  repodata_addfileprovides_search(data, cbd);
	  if (cbd->todo_start >= cbd->todo_end)
	    break;
	}
    }

  map_free(&todo);
  cbd->todo = 0;
  map_free(&providedids);
  cbd->providedids = 0;
}
示例#28
0
文件: main.c 项目: dolfly/nmdb
int main(int argc, char **argv)
{
	struct cache *cd;
	struct queue *q;
	struct db_conn *db;
	pid_t pid;
	pthread_t *dbthread;

	if (!load_settings(argc, argv))
		return 1;

	if (!log_init()) {
		perror("Error opening log file");
		return 1;
	}

	stats_init(&stats);

	cd = cache_create(settings.numobjs, 0);
	if (cd == NULL) {
		errlog("Error creating cache");
		return 1;
	}
	cache_table = cd;

	q = queue_create();
	if (q == NULL) {
		errlog("Error creating queue");
		return 1;
	}
	op_queue = q;

	db = db_open(settings.backend, settings.dbname, 0);
	if (db == NULL) {
		errlog("Error opening DB");
		return 1;
	}
	wlog("Opened database \"%s\" with %s backend\n", settings.dbname,
		be_str_from_type(settings.backend));

	if (!settings.foreground) {
		pid = fork();
		if (pid > 0) {
			/* parent exits */
			return 0;
		} else if (pid < 0) {
			errlog("Error in fork()");
			return 1;
		}

		close(0);
		setsid();
	}

	wlog("Starting nmdb\n");

	write_pid();

	dbthread = db_loop_start(db);

	net_loop();

	db_loop_stop(dbthread);

	db->close(db);

	queue_free(q);

	cache_free(cd);

	if (settings.pidfile)
		unlink(settings.pidfile);

	free_settings();

	return 0;
}
示例#29
0
文件: testsolv.c 项目: ryppl/libsolv
int
main(int argc, char **argv)
{
  Pool *pool;
  Queue job;
  Solver *solv;
  char *result = 0;
  int resultflags = 0;
  int debuglevel = 0;
  int writeresult = 0;
  int multijob = 0;
  int c;
  int ex = 0;
  FILE *fp;

  while ((c = getopt(argc, argv, "vrh")) >= 0)
    {
      switch (c)
      {
        case 'v':
          debuglevel++;
          break;
        case 'r':
          writeresult++;
          break;
        case 'h':
	  usage(0);
          break;
        default:
	  usage(1);
          break;
      }
    }
  if (optind == argc)
    usage(1);
  for (; optind < argc; optind++)
    {
      pool = pool_create();
      pool_setdebuglevel(pool, debuglevel);

      fp = fopen(argv[optind], "r");
      if (!fp)
	{
	  perror(argv[optind]);
	  exit(0);
	}
      while(!feof(fp))
	{
	  queue_init(&job);
	  result = 0;
	  resultflags = 0;
	  solv = testcase_read(pool, fp, argv[optind], &job, &result, &resultflags);
	  if (!solv)
	    {
	      pool_free(pool);
	      exit(1);
	    }

	  if (!multijob && !feof(fp))
	    multijob = 1;

	  if (multijob)
	    printf("test %d:\n", multijob++);
	  if (result || writeresult)
	    {
	      char *myresult, *resultdiff;
	      solver_solve(solv, &job);
	      if (!resultflags)
		resultflags = TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
	      myresult = testcase_solverresult(solv, resultflags);
	      if (writeresult)
		{
		  if (*myresult)
		    {
		      if (writeresult > 1)
			{
			  char *p = myresult;
			  while (*p)
			    {
			      char *p2 = strchr(p, '\n');
			      p2 = p2 ? p2 + 1 : p + strlen(p);
			      printf("#>%.*s", (int)(p2 - p), p);
			      p = p2;
			    }
			}
		      else
			printf("%s", myresult);
		    }
		}
	      else
		{
		  resultdiff = testcase_resultdiff(result, myresult);
		  if (resultdiff)
		    {
		      printf("Results differ:\n%s", resultdiff);
		      ex = 1;
		      solv_free(resultdiff);
		    }
		}
	      solv_free(result);
	      solv_free(myresult);
	    }
	  else
	    {
	      if (solver_solve(solv, &job))
		{
		  int problem, solution, pcnt, scnt;
		  pcnt = solver_problem_count(solv);
		  printf("Found %d problems:\n", pcnt);
		  for (problem = 1; problem <= pcnt; problem++)
		    {
		      printf("Problem %d:\n", problem);
		      solver_printprobleminfo(solv, problem);
		      printf("\n");
		      scnt = solver_solution_count(solv, problem);
		      for (solution = 1; solution <= scnt; solution++)
			{
			  printf("Solution %d:\n", solution);
			  solver_printsolution(solv, problem, solution);
			  printf("\n");
			}
		    }
		}
	      else
		{
		  Transaction *trans = solver_create_transaction(solv);
		  printf("Transaction summary:\n\n");
		  transaction_print(trans);
		  transaction_free(trans);
		}
	    }
	  queue_free(&job);
	  solver_free(solv);
	}
      pool_free(pool);
    }
  exit(ex);
}
示例#30
0
/*
*   Build Non-Deterministic Finite Automata
*/ 
static void Build_DFA (ACSM_STRUCT * acsm) 
{
	int r, s;
	int i;
	QUEUE q, *queue = &q;
	ACSM_PATTERN * mlist=0;
	ACSM_PATTERN * px=0;

	/* Init a Queue */ 
	queue_init (queue);

	/* Add the state 0 transitions 1st */
	/*1st depth Node's FailState is 0, fail(x)=0 */
	for (i = 0; i < ALPHABET_SIZE; i++)
	{
		s = acsm->acsmStateTable[0].NextState[i];
		if (s)
		{
			queue_add (queue, s);
			acsm->acsmStateTable[s].FailState = 0;
		}
	}

	/* Build the fail state transitions for each valid state */ 
	while (queue_count (queue) > 0)
	{
		r = queue_remove (queue);

		/* Find Final States for any Failure */ 
		for (i = 0; i < ALPHABET_SIZE; i++)
		{
			int fs, next;
			/*** Note NextState[i] is a const variable in this block ***/
			if ((s = acsm->acsmStateTable[r].NextState[i]) != ACSM_FAIL_STATE)
			{
				queue_add (queue, s);
				fs = acsm->acsmStateTable[r].FailState;

				/* 
				*  Locate the next valid state for 'i' starting at s 
				*/ 
				/**** Note the  variable "next" ****/
				/*** Note "NextState[i]" is a const variable in this block ***/
				while ((next=acsm->acsmStateTable[fs].NextState[i]) ==
					ACSM_FAIL_STATE)
				{
					fs = acsm->acsmStateTable[fs].FailState;
				}

				/*
				*  Update 's' state failure state to point to the next valid state
				*/ 
				acsm->acsmStateTable[s].FailState = next;

                                
                                ACSM_PATTERN* pat = acsm->acsmStateTable[next].MatchList;
                                for (; pat != NULL; pat = pat->next)
                                {
                                    AddMatchListEntry(acsm, s, pat);    
                                }
			}
			else
			{
				acsm->acsmStateTable[r].NextState[i] =
					acsm->acsmStateTable[acsm->acsmStateTable[r].FailState].NextState[i];
			}
		}
	}

	/* Clean up the queue */ 
	queue_free (queue);
}