struct int_list_type *reachable_states_bounded_steps(DFA *M, int c1, int c2){ paths state_paths, pp; int current; int steps; int sink = find_sink(M); struct int_list_type *worklist=NULL; struct int_list_type *nextlist=NULL; struct int_list_type *finallist = new_ilt(); worklist = enqueue(worklist, M->s); for(steps=1; steps <=c2; steps++){ while(worklist->count>0){ current = dequeue(worklist); //dequeue returns the int value instead of the struct state_paths = pp = make_paths(M->bddm, M->q[current]); while (pp) { if(pp->to != sink){ nextlist=enqueue(nextlist, pp->to); if(steps >= c1) finallist = enqueue(finallist, pp->to); } pp = pp->next; } } if(!nextlist) break; free(worklist); worklist = nextlist; nextlist = NULL; } print_ilt(finallist); return finallist; }
/** * Muath documentation: * returns 1 (true) if there is a transition out of state 'state' not equal to lambda * end Muath documentation */ int isOtherLambdaOut(DFA* M, char* lambda, int state, int var){ char* symbol; paths state_paths, pp; trace_descr tp; int j, sink; sink = find_sink(M); assert(sink >= 0); symbol = (char *) malloc((var + 1) * sizeof(char)); state_paths = pp = make_paths(M->bddm, M->q[state]); while (pp) { if (pp->to != sink) { for (j = 0, tp = pp->trace; j < var && tp; j++, tp = tp->next) { if (tp) { if (tp->value) symbol[j] = '1'; else symbol[j] = '0'; } else symbol[j] = 'X'; } symbol[j] = '\0'; if (isNotExactEqual2Lambda(symbol, lambda, var)) return 1; } pp = pp->next; } //end while return 0; }
bool isLengthFiniteTarjan(DFA *M, int var, int *indices) { if (check_emptiness_minimized(M) || checkOnlyEmptyString(M, var, indices)) { return true; } int node; int SCCcount=0; bool sccFound = false; // we need sink just for printing int sink = find_sink(M); assert(sink >= 0); // convert dfa->graph, if there is any self cycle, stop and return if (dfa_to_graph(M)){ return false; } vertexStatus=(int*) malloc(numOfNodes*sizeof(int)); secondDFSrestarts=(int*) malloc(numOfNodes*sizeof(int)); if (!vertexStatus || !secondDFSrestarts) { printf("malloc failedn"); exit(0); } // DFS code for (node=0;node<numOfNodes;node++) vertexStatus[node]=WHITE; finishIndex=numOfNodes; for (node=0;node<numOfNodes;node++) if (vertexStatus[node]==WHITE) DFSvisit(node); reverseEdges(); // DFS code for (node=0;node<numOfNodes;node++) vertexStatus[node]=WHITE; for (node=0;node<numOfNodes;node++) if (vertexStatus[secondDFSrestarts[node]]==WHITE) { SCCcount++; // printf("Strongly Connected Component %d\n",SCCcount); if(DFSvisit2(secondDFSrestarts[node], sink) == true){ // printf("Found a real SCC on node %d\n", node); sccFound = true; } } free(edgeTab); free(firstEdge); free(vertexStatus); free(secondDFSrestarts); return !sccFound; }
static gboolean create_sink (GstSplitMuxSink * splitmux) { GstElement *provided_sink = NULL; g_return_val_if_fail (splitmux->active_sink == NULL, TRUE); GST_OBJECT_LOCK (splitmux); if (splitmux->provided_sink != NULL) provided_sink = gst_object_ref (splitmux->provided_sink); GST_OBJECT_UNLOCK (splitmux); if (provided_sink == NULL) { if ((splitmux->sink = create_element (splitmux, DEFAULT_SINK, "sink")) == NULL) goto fail; splitmux->active_sink = splitmux->sink; } else { if (!gst_bin_add (GST_BIN (splitmux), provided_sink)) { g_warning ("Could not add sink elements - splitmuxsink will not work"); gst_object_unref (provided_sink); goto fail; } splitmux->active_sink = provided_sink; /* The bin holds a ref now, we can drop our tmp ref */ gst_object_unref (provided_sink); /* Find the sink element */ splitmux->sink = find_sink (splitmux->active_sink); if (splitmux->sink == NULL) { g_warning ("Could not locate sink element in provided sink - splitmuxsink will not work"); goto fail; } } if (!gst_element_link (splitmux->muxer, splitmux->active_sink)) { g_warning ("Failed to link muxer and sink- splitmuxsink will not work"); goto fail; } return TRUE; fail: return FALSE; }
DFA *dfa_Prefix(DFA *M, int c1, int c2, int var, int* indices) //Output M' so that L(M')={w| w'\in \Sigma*, ww' \in L(M), c_1 <= |w|<=c_2 } { int i, sink; DFA *M1 = dfaSigmaC1toC2(c1, c2, var, indices); DFA *M2 = dfaCopy(M); //dfaPrintVerbose(M2); sink = find_sink(M); for(i=0; i<M2->ns; i++){ if(i!= sink) M2->f[i]=1; } //dfaPrintVerbose(M2); DFA *result = dfa_intersect(M2, M1); //dfaPrintVerbose(result); dfaFree(M1); dfaFree(M2); return dfaMinimize(result); }//end of prefix
unsigned dfaGetDegree(DFA *M, unsigned state){ int ssink = find_sink(M); unsigned sink; if (ssink == -1) sink = UINT_MAX; else sink = ssink; assert(state != sink); paths state_paths, pp; unsigned nextStatesSize = 16, nextStatesIndex = 0, degree = 0; unsigned *nextStates = (unsigned*) malloc((size_t) (nextStatesSize) * sizeof(unsigned)); mem_zero(nextStates, (size_t) (nextStatesSize) * sizeof(unsigned)); /******************* find node degree *********************/ state_paths = pp = make_paths(M->bddm, M->q[state]); while (pp) { if (pp->to != sink){ bool found = false; for (nextStatesIndex = 0; nextStatesIndex < degree; nextStatesIndex++) { if (pp->to == nextStates[nextStatesIndex]){ found = true; break; } } if (!found){ if (degree < nextStatesSize){ nextStates[degree] = pp->to; } else { unsigned oldSize = nextStatesSize; nextStatesSize *= 2; nextStates = (unsigned*) mem_resize(nextStates, (size_t)(nextStatesSize) * sizeof(unsigned)); mem_zero(nextStates + oldSize, (size_t) (nextStatesSize - oldSize) * sizeof(unsigned)); nextStates[degree] = pp->to; } degree++; } } pp = pp->next; } kill_paths(state_paths); free(nextStates); return degree; }
static osync_bool get_changes(Command *cmd, SyncType type, OSyncError **error) { OSyncObjTypeSink *sink = NULL; OSyncList *list; OSyncList *objtypesinks = NULL; const char *objtype = cmd->arg; if (objtype) { sink = find_sink(objtype, error); if (!sink) goto error; cmd->sink = sink; if (!get_changes_sink(cmd, sink, type, error)) goto error; } else { /* all available objtypes */ objtypesinks = osync_plugin_info_get_objtype_sinks(plugin_info); list = objtypesinks; while(list) { sink = (OSyncObjTypeSink*)list->data; cmd->sink = sink; if (!get_changes_sink(cmd, sink, type, error)) goto error; list = list->next; } /* last but not least - the main sink */ if (get_main_sink()) if (!get_changes_sink(cmd, get_main_sink(), type, error)) goto error; osync_list_free(objtypesinks); } return TRUE; error: osync_list_free(objtypesinks); return FALSE; }
unsigned dfaGetMaxDegree(DFA *M, unsigned *p_maxState){ int ssink = find_sink(M); unsigned sink; if (ssink == -1) sink = UINT_MAX; else sink = ssink; unsigned state = 0, maxState = 0, maxDegree = 0, degree = 0; for (state = 0; state < M->ns; state++){ degree = dfaGetDegree(M, state); if (maxDegree < degree){ maxDegree = degree; maxState = state; } } *p_maxState = maxState; return maxDegree; }
static osync_bool commit(Command *cmd, OSyncChange *change, OSyncError **error) { OSyncList *list; OSyncList *objtypesinks = NULL; OSyncObjTypeSink *sink = NULL; const char *objtype = cmd->arg; assert(change); if (objtype) { sink = find_sink(objtype, error); if (!sink) goto error; if (!commit_sink(cmd, sink, change, error)) goto error; } else { objtypesinks = osync_plugin_info_get_objtype_sinks(plugin_info); list = objtypesinks; while(list){ sink = (OSyncObjTypeSink*)list->data; if (!commit_sink(cmd, sink, change, error)) goto error; list = list->next; } /* last but not least - the main sink */ if (get_main_sink()) if (!commit_sink(cmd, get_main_sink(), change, error)) goto error; osync_list_free(objtypesinks); } return TRUE; error: osync_list_free(objtypesinks); return FALSE; }
/** * Muath documentation: * returns a list of states containing each state s that has at least one transition on lambda * into it and one transition on non-lambda out of it (except for sink state which is ignored) * end Muath documentation */ struct int_list_type *reachable_states_lambda_in_nout(DFA *M, char *lambda, int var){ paths state_paths, pp; trace_descr tp; int j, current; int sink = find_sink(M); char *symbol; struct int_list_type *finallist=NULL; if(_FANG_DFA_DEBUG)dfaPrintVerbose(M); symbol=(char *)malloc((var+1)*sizeof(char)); for(current=0; current<M->ns; current++){ state_paths = pp = make_paths(M->bddm, M->q[current]); while (pp) { if(pp->to != sink){ // construct transition from current to pp->to and store it in symbol for (j = 0, tp = pp->trace; j < var && tp; j++, tp = tp->next) { if (tp) { if (tp->value) symbol[j]='1'; else symbol[j]='0'; } else symbol[j]='X'; } symbol[j]='\0'; // if transition from current state to pp->to state is on labmda if(isEqual2Lambda(symbol, lambda, var)){ // if there is a transition out of pp->to state on non-lambda then add pp->to to returned list if(isOtherLambdaOut(M, lambda, (pp->to), var)) finallist = enqueue(finallist, pp->to); } } pp = pp->next; } } if(_FANG_DFA_DEBUG) print_ilt(finallist); free(symbol); return finallist; }
/* TODO: should return transition relation with the sink in it then add a function to remove the sink. This will break Tarjan length algorithm so it should be changed to take relation after removing the sink. it will also break pre_add_slashes which should not do any shifting */ pTransitionRelation dfaGetTransitionRelation(DFA *M){ unsigned state, degree, nextState, i; state = degree = nextState = 0; paths state_paths, pp; int sink = find_sink(M); assert(sink >= 0);//assert that there is a sink pTransitionRelation p_transitionRelation = (pTransitionRelation) malloc(sizeof(transitionRelation)); p_transitionRelation->reverse = false; p_transitionRelation->selfCycles = false; p_transitionRelation->sink = (unsigned)sink; p_transitionRelation->num_of_nodes = M->ns - 1; p_transitionRelation->num_of_edges = 0; p_transitionRelation->adjList = (unsigned**) malloc((size_t) (p_transitionRelation->num_of_nodes) * sizeof(unsigned*)); mem_zero(p_transitionRelation->adjList, (size_t) p_transitionRelation->num_of_nodes * sizeof(unsigned*) ); p_transitionRelation->degrees = (t_st_word*) malloc((size_t) (p_transitionRelation->num_of_nodes) * sizeof(t_st_word)); mem_zero(p_transitionRelation->degrees, (size_t) p_transitionRelation->num_of_nodes * sizeof(t_st_word)); bool *nextStates = (bool*) malloc((size_t) (p_transitionRelation->num_of_nodes) * sizeof(bool)); unsigned numOfAcceptStates = 0; // a heuristic assuming 1/20th of states are accepting unsigned acceptSizeTemp = (M->ns < 100)? 4 : roundToNextPow2(M->ns / 20); p_transitionRelation->acceptsSize = (p_transitionRelation->num_of_nodes < acceptSizeTemp)? p_transitionRelation->num_of_nodes : acceptSizeTemp; p_transitionRelation->accepts = (unsigned *) mem_alloc((size_t) p_transitionRelation->acceptsSize * sizeof(unsigned)); mem_zero(p_transitionRelation->accepts, (size_t) p_transitionRelation->acceptsSize * sizeof(unsigned)); for (i = 0; i < M->ns; i++){ if (M->f[i] == 1){ p_transitionRelation->accepts[numOfAcceptStates++] = (i < sink)? i : i - 1; if (numOfAcceptStates == p_transitionRelation->acceptsSize){ unsigned acceptSizeTemp = p_transitionRelation->acceptsSize * 2; p_transitionRelation->acceptsSize = (p_transitionRelation->num_of_nodes < acceptSizeTemp)? p_transitionRelation->num_of_nodes : acceptSizeTemp; p_transitionRelation->accepts = (unsigned*) mem_resize(p_transitionRelation->accepts, (size_t) p_transitionRelation->acceptsSize * sizeof(unsigned)); mem_zero(p_transitionRelation->accepts + numOfAcceptStates, (size_t) (p_transitionRelation->acceptsSize - numOfAcceptStates) * sizeof(unsigned)); } } if (sink == i) continue; else if (sink < i) state = i - 1;//shift state else state = i; // printf("i = %d for state = %u\n", i, state); /******************* find node degree *********************/ memset(nextStates, false, sizeof(bool) * (p_transitionRelation->num_of_nodes)); state_paths = pp = make_paths(M->bddm, M->q[i]); while (pp) { if (pp->to == i) p_transitionRelation->selfCycles = true; unsigned to = (sink < pp->to)? pp->to - 1 : pp->to; if (pp->to != sink){ if (nextStates[to] == false){ nextStates[to] = true; p_transitionRelation->degrees[state]++; p_transitionRelation->num_of_edges++; } } pp = pp->next; } kill_paths(state_paths); /******************* allocate node's adjacency list and fill it up *********************/ if (p_transitionRelation->degrees[state] == 0) { p_transitionRelation->adjList[state] = NULL; } else { p_transitionRelation->adjList[state] = (unsigned *) malloc((size_t) (p_transitionRelation->degrees[state]) * sizeof(unsigned) ); mem_zero(p_transitionRelation->adjList[state],(size_t) (p_transitionRelation->degrees[state]) * sizeof(unsigned)); for (nextState = 0, degree = 0; nextState < p_transitionRelation->num_of_nodes; nextState++) { if (nextStates[nextState] == true){ assert(degree < p_transitionRelation->degrees[state]); p_transitionRelation->adjList[state][degree] = nextState; degree++; } } } } p_transitionRelation->acceptsSize = numOfAcceptStates; p_transitionRelation->accepts = (unsigned*) mem_resize((p_transitionRelation->accepts), ((p_transitionRelation->acceptsSize) * sizeof(unsigned))); qsort(p_transitionRelation->accepts, p_transitionRelation->acceptsSize, sizeof(unsigned), intcmpfunc); free(nextStates); return p_transitionRelation; }
DFA *dfa_Suffix(DFA *M, int c1, int c2, int var, int *oldindices) { DFA *result = NULL; DFA *tmpM = NULL; int aux=0; struct int_list_type *states=NULL; struct int_type *tmpState=NULL; int maxCount = 0; int *indices = oldindices; //indices is updated if you need to add auxiliary bits paths state_paths, pp; trace_descr tp; int i, j, z, k; char *exeps; int *to_states; long max_exeps; char *statuces; int len=var; int sink; char *auxbit=NULL; // char *apath =bintostr(a, var); states = reachable_states_bounded_steps(M, c1, c2); maxCount = states->count; if(maxCount>0){ //Need auxiliary bits when there exist some outgoing edges aux = get_hsig(maxCount); if(_FANG_DFA_DEBUG) printf("\n There are %d reachable states, need to add %d auxiliary bits\n", maxCount, aux); auxbit = (char *) malloc(aux*sizeof(char)); len = var+aux; // extra aux bits indices = allocateArbitraryIndex(len); } max_exeps=1<<len; //maybe exponential sink=find_sink(M); assert(sink >-1); //pairs[i] is the list of all reachable states by \sharp1 \bar \sharp0 from i dfaSetup(M->ns+1, len, indices); //add one new initial state exeps=(char *)malloc(max_exeps*(len+1)*sizeof(char)); //plus 1 for \0 end of the string to_states=(int *)malloc(max_exeps*sizeof(int)); statuces=(char *)malloc((M->ns+2)*sizeof(char)); //printf("Before Replace Char\n"); //dfaPrintVerbose(M); k=0; //setup for the initial state tmpState = states->head; for (z=1; z<=states->count; z++) { state_paths = pp = make_paths(M->bddm, M->q[tmpState->value]); while (pp) { if(pp->to!=sink){ to_states[k]=pp->to+1; //insert itself as the initial state for (j = 0; j < var; j++) { //the following for loop can be avoided if the indices are in order for (tp = pp->trace; tp && (tp->index != indices[j]); tp =tp->next); if (tp) { if (tp->value) exeps[k*(len+1)+j]='1'; else exeps[k*(len+1)+j]='0'; }else{ exeps[k*(len+1)+j]='X'; } } set_bitvalue(auxbit, aux, z); // aux = 3, z=4, auxbit 001 for (j = var; j < len; j++) { //set to xxxxxxxx100 exeps[k*(len+1)+j]=auxbit[len-j-1]; } exeps[k*(len+1)+len]='\0'; k++; } pp = pp->next; }//end while kill_paths(state_paths); tmpState = tmpState->next; } //end for dfaAllocExceptions(k); for(k--;k>=0;k--) dfaStoreException(to_states[k],exeps+k*(len+1)); dfaStoreState(sink+1); if(check_accept(M, states)) statuces[0]='+'; else statuces[0]='0'; //for the rest of states (shift one state) for (i = 0; i < M->ns; i++) { state_paths = pp = make_paths(M->bddm, M->q[i]); k=0; while (pp) { if(pp->to!=sink){ for (tp = pp->trace; tp && (tp->index != indices[var]); tp =tp->next); //find the bar value if (!tp || !(tp->value)) { to_states[k]=pp->to+1; for (j = 0; j < var; j++) { //the following for loop can be avoided if the indices are in order for (tp = pp->trace; tp && (tp->index != indices[j]); tp =tp->next); if (tp) { if (tp->value) exeps[k*(len+1)+j]='1'; else exeps[k*(len+1)+j]='0'; } else exeps[k*(len+1)+j]='X'; } for (j = var; j < len; j++) { exeps[k*(len+1)+j]='0'; } exeps[k*(len+1)+len]='\0'; k++; } } pp = pp->next; }//end while dfaAllocExceptions(k); for(k--;k>=0;k--) dfaStoreException(to_states[k],exeps+k*(len+1)); dfaStoreState(sink+1); if(M->f[i]==1) statuces[i+1]='+'; else if(M->f[i]==-1) statuces[i+1]='-'; else statuces[i+1]='0'; kill_paths(state_paths); } statuces[M->ns+1]='\0'; result=dfaBuild(statuces); // dfaPrintVerbose(result); for(i=0; i<aux; i++){ j=len-i-1; tmpM =dfaProject(result, (unsigned) j); dfaFree(result); result = dfaMinimize(tmpM); dfaFree(tmpM); // printf("\n After projecting away %d bits", j); // dfaPrintVerbose(result); } free(exeps); //printf("FREE ToState\n"); free(to_states); //printf("FREE STATUCES\n"); free(statuces); if(maxCount>0) free(auxbit); free_ilt(states); return dfaMinimize(result); }
static void on_set_debug(pa_core* c, pa_proplist* p, int debug_sink_id, const char* ext_args) { const char* device_name = pa_proplist_gets(p, PROPLIST_KEY_DEVICE); if (!device_name) { pa_log_error("device not specific!"); return; } int device_id = atoi(device_name); pa_sink* sink = NULL; pa_source* source = NULL; sink = find_sink(c, device_id); if (!sink) { source = find_source(c, device_id); } if (!sink && !source) { pa_log_error("sink/source of device id %s not found!", device_name); return; } pa_sample_spec ss; pa_channel_map map; if (sink) { ss = sink->sample_spec; map = sink->channel_map; } else { ss = source->sample_spec; map = source->channel_map; } if (debug_sink_id == EAUDIO_STREAM_DEVICE_VIRTUALOUPUT_REMOTE) { ss.rate = 8000; ss.format = PA_SAMPLE_U8; ss.channels = 1; map.channels = 1; } char sink_name[64]; GET_PLUGIN_NAME(sink_name, debug_sink_id); pa_module* link_module = NULL; const char* str_func = pa_proplist_gets(p, PROPLIST_VALUE_FUNC); bool func_on = true; if (str_func) { func_on = !strcmp(str_func, PROPLIST_VALUE_TRUE); } if (sink) { link_module = sink->module; } else if (source) { link_module = source->module; } if (func_on) { pa_pre_load_func_t f = pa_get_user_data(PA_USER_SINK_PRELOAD_FUNC); if (f) { f(sink_name, c, &ss, &map, ext_args); } pa_sink* remote_sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK); if (!remote_sink) { pa_log_error("remote-sink load failed"); return; } char args[256] = { 0 }; char loopback_name[128] = { 0 }; const char* i_name = NULL; const char* o_name = NULL; if (sink) { i_name = sink->monitor_source->name; o_name = remote_sink->name; } else if (source) { i_name = source->name; o_name = remote_sink->name; } pa_snprintf(loopback_name, sizeof(loopback_name), "Loopback(%s->%s)", i_name, o_name); pa_snprintf(args, sizeof(args), "name=%s source=%s sink=%s token=%u %s", loopback_name, i_name, o_name, MAGIC_TOKEN_ID, ext_args ? ext_args : ""); pa_log_info("load-module module-loopback args: %s", args); pa_module* m = pa_module_load(c, "module-loopback", args); if (!m) { pa_log_error("on_set_debug module load err."); return; } if (link_module) { pa_proplist_sets(link_module->proplist, PA_PROP_LINK_LOOPBACK_ID, loopback_name); } } else { pa_sink* remote_sink = find_sink(c, debug_sink_id); if (remote_sink) { pa_log_info("unloading remote_sink %d", debug_sink_id); pa_module_unload_request(remote_sink->module, true); } } }
void on_set_common(pa_proplist* p, pa_tagstruct* t, pa_core* c) { pa_log_info("on_set_common"); const char* attribute = pa_proplist_gets(p, PROPLIST_KEY_ATTRIBUTE); if (!attribute) { pa_log_error("on_set_common: attribute not found!"); return; } if (!strcmp(attribute, PROPLIST_VALUE_GET_INFO)) { const char* str_device = pa_proplist_gets(p, PROPLIST_KEY_DEVICE); if (!str_device) { pa_log_error("on_set_common device not specific!"); return; } int device_id = atoi(str_device); pa_sink* sink = NULL; pa_source* source = NULL; sink = find_sink(c, device_id); if (!sink) { source = find_source(c, device_id); } if (!sink && !source) { pa_log_error("do not find any sink or source of device %d", device_id); return; } int n_used = 0; if (sink) { n_used = pa_module_get_n_used(sink->module); } else { n_used = pa_module_get_n_used(source->module); } char value[32]; snprintf(value, sizeof(value), "%d", n_used); pa_proplist* replyp = pa_proplist_new(); pa_proplist_sets(replyp, PROPLIST_KEY_VALUE, value); pa_tagstruct_put_proplist(t, replyp); pa_proplist_free(replyp); } else if (!strcmp(attribute, PROPLIST_VALUE_REMOTE_SINK)) { #ifdef HAVE_WEB_SOCKET extern void start_web_socket(); start_web_socket(); #endif on_set_debug(c, p, EAUDIO_STREAM_DEVICE_VIRTUALOUPUT_REMOTE, NULL); } else if (!strcmp(attribute, PROPLIST_VALUE_FILE_SINK)) { const char* str_path = pa_proplist_gets(p, PROPLIST_VALUE_PATH); char args[64] = { 0 }; if (str_path) { snprintf(args, sizeof(args), "path=%s", str_path); } on_set_debug(c, p, EAUDIO_STREAM_DEVICE_VIRTUALOUPUT_FILE, str_path ? args : NULL); } else if (!strcmp(attribute, PROPLIST_VALUE_ALSA_BUFFER)) { const char* str_device = pa_proplist_gets(p, PROPLIST_KEY_DEVICE); if (!str_device) { pa_log_error("on_set_common alsa-buffer device not specific!"); return; } int device = atoi(str_device); pa_sink* s = find_sink(c, device); if (!s) { pa_log_error("sink not found %d", device); return; } pa_usec_t left_to_play = pa_sink_get_left_to_play(s); pa_proplist* replyp = pa_proplist_new(); pa_proplist_set(replyp, PROPLIST_KEY_COMMAND_RESULT, &left_to_play, sizeof(left_to_play)); pa_tagstruct_put_proplist(t, replyp); pa_proplist_free(replyp); } else if (!strcmp(attribute, PROPLIST_VALUE_STOP_TEST)) { pthread_t tid_stop; int err = pthread_create(&tid_stop, NULL, stop_thread, NULL); if (err != 0) { pa_log_error("can't create thread: %s\n", strerror(err)); return; } } #ifdef HAVE_WEB_SOCKET else if (!strcmp(attribute, "web-start")) { extern void start_web_socket(); start_web_socket(); } else if (!strcmp(attribute, "web-stop")) { extern void stop_web_socket(); stop_web_socket(); } #endif }