int main(int argc, char **argv) { lnode *head = NULL; char *new_string = (char *)malloc(sizeof(char)*(strlen("abcd")+1)); strcpy(new_string, "abcd"); lnode *new_node = lnode_insert(&head, new_string); new_string = (char *)malloc(sizeof(char)*(strlen("efgh")+1)); strcpy(new_string, "efgh"); new_node = lnode_insert(&head, new_string); new_string = (char *)malloc(sizeof(char)*(strlen("wxyz")+1)); strcpy(new_string, "wxyz"); new_node = lnode_insert(&head, new_string); new_node = head; while (new_node != NULL) { printf("%s->", new_node->str); new_node = new_node->next; } printf("NULL\n"); while (head != NULL) { lnode *removed_node = lnode_remove(&head); printf("%s\n", removed_node->str); lnode_destroy(removed_node); } lnode_destroy(head); return EXIT_SUCCESS; }
/*Creates the root node and the corresponding lnode*/ error_t node_create_root (node_t ** root_node) { /*Try to create a new lnode */ lnode_t *lnode; error_t err = lnode_create (NULL, &lnode); /*Stop, if the creation failed */ if (err) return err; /*Try to derive the node corresponding to `lnode` */ node_t *node; err = node_create (lnode, &node); /*If the operation failed */ if (err) { /*destroy the created lnode */ lnode_destroy (lnode); /*stop */ return err; } /*Release the lock on the lnode */ mutex_unlock (&lnode->lock); /*Store the result in the parameter */ *root_node = node; /*Return the result */ return err; } /*node_create_root */
list_t* termFreeVars(TERM *t) { list_t *vars, *rvars; lnode_t *node; switch(t->type) { case(TM_VAR): vars = list_create(LISTCOUNT_T_MAX); list_append(vars, lnode_create(t->name)); break; case(TM_ALIAS): vars = list_create(LISTCOUNT_T_MAX); break; case(TM_ABSTR): vars = termFreeVars(t->rterm); while(node = list_find(vars, t->lterm->name, (int(*)(const void*, const void*))strcmp)) lnode_destroy(list_delete(vars, node)); break; case(TM_APPL): vars = termFreeVars(t->lterm); rvars = termFreeVars(t->rterm); list_transfer(vars, rvars, list_first(rvars)); list_destroy(rvars); break; } t->closed = list_isempty(vars); return vars; }
CP_C_API cp_status_t cp_register_logger(cp_context_t *context, cp_logger_func_t logger, void *user_data, cp_log_severity_t min_severity) { logger_t l; logger_t *lh = NULL; lnode_t *node = NULL; cp_status_t status = CP_OK; CHECK_NOT_NULL(context); CHECK_NOT_NULL(logger); cpi_lock_context(context); cpi_check_invocation(context, CPI_CF_LOGGER, __func__); do { // Check if logger already exists and allocate new holder if necessary l.logger = logger; if ((node = list_find(context->env->loggers, &l, comp_logger)) == NULL) { lh = malloc(sizeof(logger_t)); node = lnode_create(lh); if (lh == NULL || node == NULL) { status = CP_ERR_RESOURCE; break; } lh->logger = logger; lh->plugin = context->plugin; list_append(context->env->loggers, node); } else { lh = lnode_get(node); } // Initialize or update the logger holder lh->user_data = user_data; lh->min_severity = min_severity; // Update global limits update_logging_limits(context); } while (0); // Report error if (status == CP_ERR_RESOURCE) { cpi_error(context, N_("Logger could not be registered due to insufficient memory.")); } else if (cpi_is_logged(context, CP_LOG_DEBUG)) { char owner[64]; /* TRANSLATORS: %s is the context owner */ cpi_debugf(context, N_("%s registered a logger."), cpi_context_owner(context, owner, sizeof(owner))); } cpi_unlock_context(context); // Release resources on error if (status != CP_OK) { if (node != NULL) { lnode_destroy(node); } if (lh != NULL) { free(lh); } } return status; }
static void process_unregister_logger(list_t *list, lnode_t *node, void *plugin) { logger_t *lh = lnode_get(node); if (plugin == NULL || lh->plugin == plugin) { list_delete(list, node); lnode_destroy(node); free(lh); } }
static void client_remove( list_t *client_sockets, ClientInfo *cinfo ){ lnode_t *node; for( node = list_first( client_sockets ); node != NULL; node=node->next ){ if( node->data == cinfo ) { list_delete( client_sockets, node ); lnode_destroy( node ); return; } } }
/* Remove a reference to NODE, which must be locked. If that was the last reference, destroy the node, otherwise simply unlock NODE. */ void lnode_ref_remove (lnode_t *node) { assert (node->references); if (! --node->references) { lnode_uninstall (node); lnode_destroy (node); } else mutex_unlock (&node->lock); }
CP_HIDDEN int cpi_ptrset_remove(list_t *set, const void *ptr) { lnode_t *node; // Find the pointer if it is in the set node = list_find(set, ptr, cpi_comp_ptr); if (node != NULL) { list_delete(set, node); lnode_destroy(node); return 1; } else { return 0; } }
void list_destroy(List* list) { ListNode* node; if ((node = list->start)!= NULL) { do { ListNode* tail = node; node = node->next; lnode_destroy(tail); list->len--; } while (node!=NULL); } free(list); }
void list_destroy_nodes(list_t *list) { lnode_t *lnode = list_first_priv(list), *nil = list_nil(list), *tmp; while (lnode != nil) { tmp = lnode->next; lnode->next = NULL; lnode->prev = NULL; lnode_destroy(lnode); lnode = tmp; } list_init(list, list->maxcount); }
CP_C_API void cp_destroy_context(cp_context_t *context) { CHECK_NOT_NULL(context); if (context->plugin != NULL) { cpi_fatalf(_("Only the main program can destroy a plug-in context.")); } // Check invocation cpi_lock_context(context); cpi_check_invocation(context, CPI_CF_ANY, __func__); cpi_unlock_context(context); #ifdef CP_THREADS assert(context->env->mutex == NULL || !cpi_is_mutex_locked(context->env->mutex)); #else assert(!context->env->locked); #endif // Remove context from the context list cpi_lock_framework(); if (contexts != NULL) { lnode_t *node; if ((node = list_find(contexts, context, cpi_comp_ptr)) != NULL) { list_delete(contexts, node); lnode_destroy(node); } } cpi_unlock_framework(); // Unload all plug-ins cp_uninstall_plugins(context); // Unregister all plug-in loaders cp_unregister_ploaders(context); // Unregister implicit local plug-in loader, if any if (context->env->local_loader != NULL) { cp_unregister_ploader(context, context->env->local_loader); } // Release remaining information objects cpi_release_infos(context); // Free context cpi_free_context(context); }
CP_C_API void cp_unregister_logger(cp_context_t *context, cp_logger_func_t logger) { logger_t l; lnode_t *node; CHECK_NOT_NULL(context); CHECK_NOT_NULL(logger); cpi_lock_context(context); cpi_check_invocation(context, CPI_CF_LOGGER, __func__); l.logger = logger; if ((node = list_find(context->env->loggers, &l, comp_logger)) != NULL) { logger_t *lh = lnode_get(node); list_delete(context->env->loggers, node); lnode_destroy(node); free(lh); update_logging_limits(context); } if (cpi_is_logged(context, CP_LOG_DEBUG)) { char owner[64]; /* TRANSLATORS: %s is the context owner */ cpi_debugf(context, N_("%s unregistered a logger."), cpi_context_owner(context, owner, sizeof(owner))); } cpi_unlock_context(context); }
CP_HIDDEN void cpi_process_free_ptr(list_t *list, lnode_t *node, void *dummy) { void *ptr = lnode_get(node); list_delete(list, node); lnode_destroy(node); free(ptr); }
int main_loop( CamConfig *ccfg, Socket *picture_sock, char *picture_mem ){ Socket *listen_socket; SockSet *readset = NULL, *writeset = NULL; list_t *client_sockets; lnode_t *node; int cfg_listen_port, highest_fd, picture_client_ready; int num_sclients, num_clients; ClientInfo *clientinfo, *clientinfo2; if( (client_sockets = list_create( -1 )) == NULL) return -1; cfg_listen_port = camconfig_query_def_int( ccfg, SEC_SOCKET, "listen_port", CAMCONFIG_DEF_LISTEN_PORT ); if( (readset = sockset_new()) == NULL || (writeset = sockset_new()) == NULL ) { camserv_log( MODNAME, "Error allocating memory for socksets!"); if( readset ) sockset_dest( readset ); if( writeset ) sockset_dest( writeset ); list_destroy( client_sockets ); return -1; } if((listen_socket = socket_serve_tcp( NULL, cfg_listen_port, 100 )) == NULL ) { camserv_log( MODNAME, "Error setting up socket on port \"%d\". Exiting", cfg_listen_port ); list_destroy( client_sockets ); sockset_dest( readset ); sockset_dest( writeset ); return -1; } highest_fd = MAX( socket_query_fd( listen_socket ), socket_query_fd( picture_sock )); clientinfo = clientinfo_new( listen_socket ); clientinfo2 = clientinfo_new( picture_sock ); if( !clientinfo || !clientinfo2 || sockset_add_fd( readset, listen_socket, clientinfo ) == -1 || sockset_add_fd( readset, picture_sock, clientinfo2 ) == -1 ) { camserv_log( MODNAME, "Error adding initial sockets to sockset!"); sockset_dest( readset ); sockset_dest( writeset ); if( clientinfo ) clientinfo_dest( clientinfo ); if( clientinfo2 ) clientinfo_dest( clientinfo2 ); list_destroy( client_sockets ); return -1; } num_clients = 0; num_sclients = 0; picture_client_ready = 1; setup_signals(); Abort = 0; while( !Abort ){ int sel_res, i, nset_socks; void **set_socks; /* Only need to execute this if we have a streaming client */ if( (num_sclients > 0) && picture_client_ready == 1 ){ send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 ); picture_client_ready = 0; } sockset_reset( readset ); sockset_reset( writeset ); sel_res = sockset_select( highest_fd + 1, readset, writeset, NULL ); /* Service the event */ if( sel_res == -1 ){ camserv_log( MODNAME, "select() failure: %s", strerror( errno )); break; } else if( sel_res == 0 ){ camserv_log( MODNAME, "Unexpected select() fall through!" ); continue; } /* Readable sockets */ set_socks = sockset_query_socks( readset ); nset_socks = sockset_query_nsocks( readset ); for( i=0; i< nset_socks; i++ ){ ClientInfo *new_cinfo; clientinfo = set_socks[ i ]; if( clientinfo->socket == listen_socket ) { /* New client */ if( (new_cinfo = accept_client( listen_socket )) == NULL ) continue; if( (node = lnode_create( new_cinfo )) == NULL ){ clientinfo_dest( new_cinfo ); continue; } if( sockset_add_fd( readset, new_cinfo->socket, new_cinfo ) == -1 ){ camserv_log( MODNAME, "Failed to add socket %d to socket read set!", socket_query_fd( new_cinfo->socket )); clientinfo_dest( new_cinfo ); lnode_destroy( node ); continue; } if( socket_query_fd( new_cinfo->socket ) > highest_fd ) highest_fd = socket_query_fd( new_cinfo->socket ); list_append( client_sockets, node ); num_clients++; /* Init resource limit for this client */ new_cinfo->create_time = time( NULL ); new_cinfo->bytes = 0; new_cinfo->frames = 0; new_cinfo->max_seconds = camconfig_query_def_int( ccfg, SEC_SOCKET, "max_seconds", 0 ); new_cinfo->max_bytes = camconfig_query_def_int( ccfg, SEC_SOCKET, "max_bytes", 0 ); new_cinfo->max_frames = camconfig_query_def_int( ccfg, SEC_SOCKET, "max_frames", 0 ); /* Send fresh request for a picture */ send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 ); picture_client_ready = 0; /* Put this read socket on hold until the picture comes back */ sockset_hold( readset, new_cinfo->socket ); } else { char cmdbuf[ 1024 ]; int readlen; clientinfo = set_socks[ i ]; /* Regular joe client, set readable */ if( (readlen = read( socket_query_fd( clientinfo->socket), cmdbuf, sizeof( cmdbuf ) - 1)) <= 0 ) { camserv_log( MODNAME, "Closing socket: %s", socket_query_remote_name( clientinfo->socket )); if (clientinfo->client_type == CLIENT_T_BROWSER || clientinfo->client_type == CLIENT_T_PROXY) { num_sclients--; } client_remove( client_sockets, clientinfo ); sockset_del_fd( readset, clientinfo->socket ); sockset_unhold_all( writeset ); sockset_del_fd( writeset, clientinfo->socket ); clientinfo_dest( clientinfo ); num_clients--; } else { if( clientinfo->socket == picture_sock ) { if( dispatch_pictaker( cmdbuf, picture_mem ) == -1 ) camserv_log( MODNAME, "Pictaker dispatch failure!"); sockset_unhold_all( writeset ); /* Release the read hold as the picture has now been taken */ sockset_unhold_all( readset ); picture_client_ready = 1; } else { /* Information from a regular client */ cmdbuf[ readlen ] = '\0'; if( clientinfo->client_type == CLIENT_T_UNINIT ) { char *preamble; int pre_size; /* Figure out what type of client we have */ if( !strncmp( cmdbuf, "GET", 3 )) { if( strstr( cmdbuf, "/singleframe" )) { clientinfo->client_type = CLIENT_T_SINGLE; } else { clientinfo->client_type = CLIENT_T_BROWSER; num_sclients++; } } else if( !strncmp( cmdbuf, "PROXY", 5 )) { clientinfo->client_type = CLIENT_T_PROXY; /* Here we are in the same state as being done writing a pic */ clientinfo->state = CINFO_STATE_PICTURE; num_sclients++; databuf_buf_set( clientinfo->writebuf, NULL, 0 ); } else clientinfo->client_type = CLIENT_T_BROWSER; if( clientinfo->client_type != CLIENT_T_PROXY ) { /* Send the initial preamble. Only now we can decide which type of preamble to send (single vs. multi-part) */ if( clientinfo->client_type == CLIENT_T_SINGLE ) preamble = get_single_preamble_text( &pre_size ); else preamble = get_multi_preamble_text( &pre_size ); databuf_buf_set( clientinfo->writebuf, preamble, pre_size ); } if( sockset_add_fd( writeset, clientinfo->socket, clientinfo ) == -1 ) { camserv_log( MODNAME, "Failed to add socket %d to write set!", socket_query_fd( clientinfo->socket )); } } } } } } if( set_socks != NULL ) free( set_socks ); /* Writable sockets */ set_socks = sockset_query_socks( writeset ); nset_socks = sockset_query_nsocks( writeset ); for( i=0; i< nset_socks; i++ ){ ClientInfo *cinfo; cinfo = set_socks[ i ]; if( cinfo->client_type == CLIENT_T_BROWSER || cinfo->client_type == CLIENT_T_SINGLE ) { int result; if( (result = write_regular_client( cinfo, writeset )) != 0 ){ /* result: 1=close requested, -1=error detected */ if( result == -1 ) camserv_log( MODNAME, "Databuf write error on socket: %s\n", socket_query_remote_name( cinfo->socket )); if (cinfo->client_type == CLIENT_T_BROWSER) { num_sclients--; } client_remove( client_sockets, cinfo ); sockset_del_fd( readset, cinfo->socket ); sockset_del_fd( writeset, cinfo->socket ); clientinfo_dest( cinfo ); num_clients--; } } else { if( write_proxy_client( cinfo, writeset ) == -1 ){ camserv_log( MODNAME, "Databuf write error on socket: %d", socket_query_fd( cinfo->socket )); /* Should be proxy, but better check */ if (cinfo->client_type == CLIENT_T_PROXY) { num_sclients--; } client_remove( client_sockets, cinfo ); sockset_del_fd( readset, cinfo->socket ); sockset_del_fd( writeset, cinfo->socket ); clientinfo_dest( cinfo ); num_clients--; } } } if( set_socks != NULL ) free( set_socks ); } camserv_log( MODNAME, "Aborting."); sockset_dest( readset ); sockset_dest( writeset ); for( node = list_first( client_sockets) ; node; node=list_next( client_sockets, node )) { clientinfo_dest( node->data ); } /* Tell the picture taker to get out! Get out! */ camserv_log( MODNAME, "Closing picture taker"); send( socket_query_fd( picture_sock ), "9", sizeof( "9" ), 0 ); sleep( 3 ); camserv_log( MODNAME, "done\n"); list_destroy_nodes( client_sockets ); list_destroy( client_sockets ); socket_dest( listen_socket ); return 0; }
/* * Delete node from list and free it */ void list_delete_destroy_node( list_t * list, lnode_t * del ) { list_delete( list, del ); lnode_destroy( del ); }
int main(void) { input_t in; list_t *l = list_create(LISTCOUNT_T_MAX); lnode_t *ln; char *tok1, *val; int prompt = 0; char *help = "a <val> append value to list\n" "d <val> delete value from list\n" "l <val> lookup value in list\n" "s sort list\n" "c show number of entries\n" "t dump whole list\n" "p turn prompt on\n" "q quit"; if (!l) puts("list_create failed"); for (;;) { if (prompt) putchar('>'); fflush(stdout); if (!fgets(in, sizeof(input_t), stdin)) break; switch(in[0]) { case '?': puts(help); break; case 'a': if (tokenize(in+1, &tok1, (char **) 0) != 1) { puts("what?"); break; } val = dupstring(tok1); ln = lnode_create(val); if (!val || !ln) { puts("allocation failure"); if (ln) lnode_destroy(ln); free(val); break; } list_append(l, ln); break; case 'd': if (tokenize(in+1, &tok1, (char **) 0) != 1) { puts("what?"); break; } ln = list_find(l, tok1, comparef); if (!ln) { puts("list_find failed"); break; } list_delete(l, ln); val = (char *) lnode_get(ln); lnode_destroy(ln); free(val); break; case 'l': if (tokenize(in+1, &tok1, (char **) 0) != 1) { puts("what?"); break; } ln = list_find(l, tok1, comparef); if (!ln) puts("list_find failed"); else puts("found"); break; case 's': list_sort(l, comparef); break; case 'c': printf("%lu\n", (unsigned long) list_count(l)); break; case 't': for (ln = list_first(l); ln != 0; ln = list_next(l, ln)) puts((char *) lnode_get(ln)); break; case 'q': exit(0); break; case '\0': break; case 'p': prompt = 1; break; default: putchar('?'); putchar('\n'); break; } } return 0; }