/* ============================================================================= * 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; }
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); }
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; }
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; }
/*----------------------------------------------------------------------*/ void sys_mbox_free(sys_mbox_t mbox) { queue_free(mbox); }
/* * 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; }
/* 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; }
/* * 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); }
void hy_advisorylist_free(HyAdvisoryList advisorylist) { queue_free(&advisorylist->queue); solv_free(advisorylist); }
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); }
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); }
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; }
void request_free( Request *t ) { queue_free( &(t->queue) ); free( t ); }
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; }
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; }
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"); }
void destroy_edges(edges_list edges) { queue_free(edges, (free_edge_func) &destroy_edge); }
/** * 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; }
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); }
/* 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; }
static void test_queue (void) { Queue* queue; queue = queue_new(); queue_free (queue); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
/* * 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); }