// check memory leak bool qmem_task_at_exit(void) { if( 0 == GCFG_MEM_EN ) { return true; } return_false_if( !printf_leak_memory() ); return_false_if( !check_all() ); return true; }
bool qmem_task_init(void) { if( 0 == GCFG_MEM_EN ) { return true; } const int interval_us = SEC_TO_US( QMEM_CHECK_INTERVAL_SEC ); const int task_id = qos_timer_open( qmem_task_entry, NULL, interval_us ); return_false_if( 0 == task_id ); return_false_if( !qos_task_set_name( task_id, "qmem_task_entry" ) ); return true; }
static bool callback_arg_exec( callback_arg_t* callback_arg ){ uverify( callback_arg_t_valid( callback_arg ) ); callback_arg_t* const p = callback_arg; const batch_callback_t callback = p->callback; void* const arg = p->arg; //log_str( "batch callback_arg_exec() run callback:<0x%08x> arg:<0x%08x>"END_LINE, callback, arg ); return_false_if( !callback( arg ) ); return_false_if( !callback_arg_set_default( p ) ); uverify( callback_arg_t_valid( p ) ); return true; }
// prev -> node -> next // => // prev -> next // return: ok? bool qdlink_delete( int id, int node_id ){ uverify( id_valid( id ) ); uverify( node_id_valid( node_id ) ); int prev_id = 0; if( node_id == qdlink_first( id ) ){ prev_id = id; } else{ prev_id = qdlink_prev( id, node_id ); // not found the node uverify( 0 != prev_id ); } return_false_if( 0 == prev_id ); node_t* const prev = (node_t*)prev_id; node_t* const node = (node_t*)node_id; node_t* const next = node->next; prev->next = next; next->prev = prev; if( GCFG_DEBUG_EN ){ node->next = NULL; node->prev = NULL; } free( node ); return true; }
// prev -> node // => // prev -> src -> node // return: ok? bool qlink_insert( int id, int node_id, int node_src ){ uverify( 0 != id ); uverify( 0 != node_id ); uverify( 0 != node_src ); int prev_id = 0; if( node_id == qlink_first( id ) ){ prev_id = id; } else{ prev_id = qlink_prev( id, node_id ); // not found the node if( 0 == prev_id ){ return false; } } uverify( 0 != prev_id ); return_false_if( !qlink_append( prev_id, node_src ) ); /* node_t* const prev = (node_t*)prev_id; node_t* const node = (node_t*)node_id; node_t* const src = (node_t*)node_src; uverify( NULL == src->next ); prev->next = src; src->next = node; */ return true; }
static bool mclose( int fid ){ uverify( 0 != fid ); fid_t* const p = (fid_t*)fid; return_false_if( 0 != close( p->linux_file_id ) ); if( GCFG_DEBUG_EN ){ memset( p, 0, sizeof( fid_t ) ); } qfree( p ); return true; }
static bool batch_auto_grow_up( int id ){ uverify( id_valid( id ) ); batch_t* const batch = (batch_t*)id; const int len = batch->len; const int increase_len = 50; const int new_len = len + increase_len; callback_arg_t* const new_list = qrealloc( batch->list, new_len * sizeof( callback_arg_t ) ); // 如果没有足够的空间,老空间没有释放,仍然存在。简单返回false,说明grow_up失败。 return_false_if( NULL == new_list ); batch->list = new_list; // 老空间内容,已经拷贝在前面,只用初始化后面一段即可。 return_false_if( !init_list( batch->list + len, increase_len ) ); batch->len = new_len; uverify( id_valid( id ) ); return true; }
static bool qmem_check_fail_printf( void* ptr ) { uverify( NULL != ptr ); mem_info_t mem_info; return_false_if( !qmem_info( &mem_info, ptr ) ); qmem_edge_t edge; return_false_if( !qmem_edge( &edge, ptr ) ); char const* file_name = file_id_to_str( mem_info.file_id ); printf( "mem check FAIL: malloc in %d@%s, ptr=0x%08x\n", mem_info.line, file_name, (int)ptr ); printf( "left edge, real:%.*s(hex: %02x%02x%02x%02x) expect:%.*s\n" , edge.left_len, edge.left , edge.left[0], edge.left[1], edge.left[2], edge.left[3] , edge.left_len, edge.left_pattern ); printf( "right edge, real:%.*s(hex: %02x%02x%02x%02x) expect:%.*s\n" , edge.right_len, edge.right , edge.right[0], edge.right[1], edge.right[2], edge.right[3] , edge.right_len, edge.right_pattern ); printf( "\n" ); return true; }
static bool check_all_callback( const mem_info_t* mem_info, int ix, void* arg ) { uverify( NULL != mem_info ); uverify( 0 <= ix ); uverify( NULL != arg ); void* const ptr = mem_info->ptr; if( !qmem_check( ptr ) ) { bool* const ok = arg; *ok = false; return_false_if( !qmem_check_fail_printf( ptr ) ); // check all memory } return true; }
// last->null // => // last->src->null // return: ok? bool qdlink_append_last( int id, int node_src ){ uverify( 0 != id ); uverify( 0 != node_src ); int last_id = 0; if( qdlink_empty( id ) ){ last_id = id; } else{ last_id = qdlink_last( id ); } uverify( 0 != last_id ); return_false_if( !qdlink_append( last_id, node_src ) ); return true; }
static int mopen( const char* path, int oflag, void* config ){ uverify( NULL != path ); const int linux_file_id = open( path, oflag ); if( -1 == linux_file_id ){ return 0; } fid_t* const p = qmalloc( sizeof( fid_t ) ); return_false_if( NULL == p ); if( GCFG_DEBUG_EN ){ memset( p, 0, sizeof( fid_t ) ); } p->linux_file_id = linux_file_id; return (int)p; }
// 把 batch 中的所有回调函数,依次执行 // 如果有一个返回false,只uverify()提示,依然执行后面的callback // return: all callback return true? // false, error & any callback return false bool batch_exec_close( int id ){ uverify( id_valid( id ) ); batch_t* const batch = (batch_t*)id; bool all_ok = true; int i = 0; for( i=0; i<batch->num; i++ ){ callback_arg_t* const p = &(batch->list[i]); if( !callback_arg_exec( p ) ){ all_ok = false; uverify( false ); } } return_false_if( !batch_close( id ) ); return all_ok; }
// prev -> node // => // prev -> src -> node // return: ok? bool qdlink_insert( int id, int node_id, int node_src ){ uverify( id_valid( id ) ); uverify( node_id_valid( node_id ) ); uverify( node_id_valid( node_src ) ); int prev_id = 0; if( node_id == qdlink_first( id ) ){ prev_id = id; } else{ prev_id = qdlink_prev( id, node_id ); // not found the node uverify( 0 != prev_id ); } uverify( 0 != prev_id ); return_false_if( !qdlink_append( prev_id, node_src ) ); return true; }
inline bool BSDUDPListener::receive (Byte* bytes, Size size, NetworkAddress& sender) { assert(0 != bytes); assert(0 < size); // FIXME: Generalize this. const bool valid = fcntl(socket.fd, F_GETFD) != -1 || errno != EBADF; report_false_if( "udp listening socket is invalid", !valid ); sockaddr_in origin; socklen_t origin_size = sizeof origin; ssize_t howmany = recvfrom(socket.fd, bytes, size, MSG_WAITALL, (sockaddr*) &origin, &origin_size); // Now that the recvfrom is on a timeout, we don't need to write errors to console if the size comes back as -1. return_false_if(-1 == howmany); sender = origin.sin_addr.s_addr; return true; }
// last->null // => // last->src->null // return: ok? bool qlink_append_last( int id, int node_src ){ uverify( 0 != id ); uverify( 0 != node_src ); int last_id = 0; if( qlink_empty( id ) ){ last_id = id; } else{ last_id = qlink_last( id ); } uverify( 0 != last_id ); return_false_if( !qlink_append( last_id, node_src ) ); /* node_t* const last = (node_t*)last_id; node_t* const src = (node_t*)node_src; uverify( NULL == src->next ); last->next = src; */ return true; }
static bool callback_arg_set_default( callback_arg_t* callback_arg ){ uverify( callback_arg_t_valid( callback_arg ) ); return_false_if( !callback_arg_set( callback_arg, batch_callback_nothing, NULL ) ); return true; }
bool linux_file_vfs_open(void){ const file_operation_t fo = { mpath_match, mopen , mclose , mread , mwrite, mfstat }; return_false_if( 0 == file_system_register_vfs( &fo ) ); return true; }