bool Genefx_ABacc_prepare( GenefxState *gfxs, int width ) { int size; if (!gfxs->need_accumulator) return true; size = (width + 31) & ~31; if (gfxs->ABsize < size) { void *ABstart = D_MALLOC( size * sizeof(GenefxAccumulator) * 3 + 31 ); if (!ABstart) { D_WARN( "out of memory" ); return false; } if (gfxs->ABstart) D_FREE( gfxs->ABstart ); gfxs->ABstart = ABstart; gfxs->ABsize = size; gfxs->Aacc = (GenefxAccumulator*) (((unsigned long)ABstart+31) & ~31); gfxs->Bacc = gfxs->Aacc + size; gfxs->Tacc = gfxs->Aacc + size + size; } gfxs->Sacc = gfxs->Dacc = gfxs->Aacc; return true; }
VoodooConnectionLink::VoodooConnectionLink( VoodooLink *link ) : VoodooConnection( link ) { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this ); input.start = 0; input.last = 0; input.end = 0; input.max = 0; output.packets = NULL; output.sending = NULL; /* Initialize all locks. */ direct_mutex_init( &output.lock ); /* Initialize all wait conditions. */ direct_waitqueue_init( &output.wait ); /* Set default buffer limit. */ input.max = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX; /* Allocate buffers. */ size_t input_buffer_size = VOODOO_CONNECTION_LINK_INPUT_BUF_MAX + VOODOO_PACKET_MAX + sizeof(VoodooPacketHeader); input.buffer = (u8*) D_MALLOC( input_buffer_size ); D_INFO( "VoodooConnection/Link: Allocated "_ZU" kB input buffer at %p\n", input_buffer_size/1024, input.buffer ); direct_tls_register( &output.tls, OutputTLS_Destructor ); }
static DFBBoolean init_shader(GLuint prog_obj, const char *prog_src, GLenum type) { char *log; GLuint shader; GLint status, log_length, char_count; GLint sourceLen; sourceLen = strlen( prog_src ); shader = glCreateShader(type); glShaderSource(shader, 1, (const char**)&prog_src, &sourceLen); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status) { glAttachShader(prog_obj, shader); glDeleteShader(shader); // mark for deletion on detach return DFB_TRUE; } else { glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); log = D_MALLOC(log_length); glGetShaderInfoLog(shader, log_length, &char_count, log); D_ERROR("GLES2/Driver: shader compilation failure:\n%s\n", log); D_FREE(log); glDeleteShader(shader); return DFB_FALSE; } }
static DFBResult localAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { CoreSurface *surface; LocalAllocationData *alloc = alloc_data; D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); D_ASSERT( alloc != NULL ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); #ifndef ANDROID_NDK /* Create aligned local system surface buffer if both base address and pitch are non-zero. */ if (dfb_config->system_surface_align_base && dfb_config->system_surface_align_pitch) { /* Make sure base address and pitch are a positive power of two. */ D_ASSERT( dfb_config->system_surface_align_base >= 4 ); D_ASSERT( !(dfb_config->system_surface_align_base & (dfb_config->system_surface_align_base-1)) ); D_ASSERT( dfb_config->system_surface_align_pitch >= 2 ); D_ASSERT( !(dfb_config->system_surface_align_pitch & (dfb_config->system_surface_align_pitch-1)) ); dfb_surface_calc_buffer_size( surface, dfb_config->system_surface_align_pitch, 0, &alloc->pitch, &alloc->size ); /* Note: The posix_memalign function requires base alignment to actually be at least four. */ int tempRet = posix_memalign( &alloc->addr, dfb_config->system_surface_align_base, alloc->size ); if ( tempRet != 0 ) { D_ERROR( "Local surface pool: Error from posix_memalign:%d with base alignment value:%d. " "%s()-%s:%d\n", tempRet, dfb_config->system_surface_align_base, __FUNCTION__, __FILE__, __LINE__ ); return DFB_FAILURE; } } else { #endif /* Create un-aligned local system surface buffer. */ dfb_surface_calc_buffer_size( surface, 8, 0, &alloc->pitch, &alloc->size ); alloc->addr = D_MALLOC( alloc->size ); if (!alloc->addr) return D_OOM(); #ifndef ANDROID_NDK } #endif D_MAGIC_SET( alloc, LocalAllocationData ); allocation->flags = CSALF_VOLATILE; allocation->size = alloc->size; return DFB_OK; }
static DFBResult Construct( IDirectFBImageProvider *thiz, ... ) { DFBResult ret = DFB_FAILURE; IDirectFBDataBuffer *buffer; CoreDFB *core; va_list tag; DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_MPEG2) va_start( tag, thiz ); buffer = va_arg( tag, IDirectFBDataBuffer * ); core = va_arg( tag, CoreDFB * ); va_end( tag ); data->base.ref = 1; data->base.buffer = buffer; data->core = core; /* Increase the data buffer reference counter. */ buffer->AddRef( buffer ); /* Initialize mpeg2 decoding. */ data->dec = MPEG2_Init( mpeg2_read_func, buffer, &data->width, &data->height ); if (!data->dec) goto error; data->stage = STAGE_INFO; /* Allocate image data. */ data->image = D_MALLOC( data->width * data->height * 4 ); if (!data->image) goto error; data->stage = STAGE_IMAGE; data->base.Destruct = IDirectFBImageProvider_MPEG2_Destruct; thiz->RenderTo = IDirectFBImageProvider_MPEG2_RenderTo; thiz->SetRenderCallback = IDirectFBImageProvider_MPEG2_SetRenderCallback; thiz->GetImageDescription = IDirectFBImageProvider_MPEG2_GetImageDescription; thiz->GetSurfaceDescription = IDirectFBImageProvider_MPEG2_GetSurfaceDescription; return DFB_OK; error: if (data->dec) MPEG2_Close(data->dec); buffer->Release( buffer ); DIRECT_DEALLOCATE_INTERFACE(thiz); return ret; }
static DFBBoolean init_program(GLuint prog_obj, char *vert_prog_name, const char *vert_prog_src, char *frag_prog_name, const char *frag_prog_src, DFBBoolean texcoords) { char *log; GLint status, log_length, char_count; if (!init_shader(prog_obj, vert_prog_src, GL_VERTEX_SHADER)) { D_ERROR("GLES2/Driver: %s failed to compile!\n", vert_prog_name); return DFB_FALSE; } if (!init_shader(prog_obj, frag_prog_src, GL_FRAGMENT_SHADER)) { D_ERROR("GLES2/Driver: %s failed to compile!\n", frag_prog_name); return DFB_FALSE; } // Bind vertex positions to "dfbPos" vertex attribute slot. glBindAttribLocation(prog_obj, GLES2VA_POSITIONS, "dfbPos"); if (texcoords) // Bind vertex texture coords to "dfbUV" vertex attribute slot. glBindAttribLocation(prog_obj, GLES2VA_TEXCOORDS, "dfbUV"); // Link the program object and check for errors. glLinkProgram(prog_obj); glValidateProgram(prog_obj); glGetProgramiv(prog_obj, GL_LINK_STATUS, &status); if (status) { // Don't need the shader objects anymore. GLuint shaders[2]; GLsizei shader_count; glGetAttachedShaders(prog_obj, 2, &shader_count, shaders); glDetachShader(prog_obj, shaders[0]); glDetachShader(prog_obj, shaders[1]); return DFB_TRUE; } else { // Report errors. Shader objects detached when program is deleted. glGetProgramiv(prog_obj, GL_INFO_LOG_LENGTH, &log_length); log = D_MALLOC(log_length); glGetProgramInfoLog(prog_obj, log_length, &char_count, log); D_ERROR("GLES2/Driver: shader program link failure:\n%s\n", log); D_FREE(log); return DFB_FALSE; } glUseProgram( prog_obj ); }
static inline bool ensure_capacity( FusionVector *vector ) { D_MAGIC_ASSERT( vector, FusionVector ); D_ASSERT( vector->capacity > 0 ); if (!vector->elements) { if (vector->pool) vector->elements = SHMALLOC( vector->pool, vector->capacity * sizeof(void*) ); else vector->elements = D_MALLOC( vector->capacity * sizeof(void*) ); if (!vector->elements) return false; } else if (vector->count == vector->capacity) { void *elements; void *oldelements = vector->elements; int capacity = vector->capacity << 1; if (vector->pool) elements = SHMALLOC( vector->pool, capacity * sizeof(void*) ); else elements = D_MALLOC( capacity * sizeof(void*) ); if (!elements) return false; direct_memcpy( elements, vector->elements, vector->count * sizeof(void*) ); vector->elements = elements; vector->capacity = capacity; if (vector->pool) SHFREE( vector->pool, oldelements ); else D_FREE( oldelements ); } return true; }
static __inline__ void *args_alloc( void *static_buffer, size_t size ) { void *buffer = static_buffer; if (size > FLUXED_ARGS_BYTES) { buffer = D_MALLOC( size ); if (!buffer) return NULL; } return buffer; }
static DirectNode * tree_node_new( DirectTree *tree, void *key, void *value ) { DirectNode *node; node = D_MALLOC(sizeof (DirectNode)); node->balance = 0; node->left = NULL; node->right = NULL; node->key = key; node->value = value; return node; }
DirectResult fusion_shm_pool_allocate( FusionSHMPoolShared *pool, int size, bool clear, bool lock, void **ret_data ) { void *data; D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); data = clear ? D_CALLOC( 1, size ) : D_MALLOC( size ); if (!data) return DR_NOSHAREDMEMORY; *ret_data = data; return DR_OK; }
/* ------------------------------------ */ int readFile (const char *filename, char **buffer, long *size) { FILE *in; char *buf; long length; in = fopen (filename, "r"); if (in == 0) { perror (filename); return -1; } fseek (in, 0, SEEK_END); length = ftell (in); rewind (in); buf = D_MALLOC(length); fread (buf, length, 1, in); fclose (in); *size = length; *buffer = buf; return length; }
static DFBResult IDirectFBImageProvider_JPEG2000_RenderTo( IDirectFBImageProvider *thiz, IDirectFBSurface *destination, const DFBRectangle *dest_rect ) { IDirectFBSurface_data *dst_data; CoreSurface *dst_surface; CoreSurfaceBufferLock lock; DFBRectangle rect; DFBRegion clip; DIRenderCallbackResult cb_result = DIRCR_OK; DFBResult ret = DFB_OK; DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_JPEG2000 ) if (!destination) return DFB_INVARG; dst_data = destination->priv; if (!dst_data || !dst_data->surface) return DFB_DESTROYED; dst_surface = dst_data->surface; if (dest_rect) { if (dest_rect->w < 1 || dest_rect->h < 1) return DFB_INVARG; rect = *dest_rect; rect.x += dst_data->area.wanted.x; rect.y += dst_data->area.wanted.y; } else { rect = dst_data->area.wanted; } dfb_region_from_rectangle( &clip, &dst_data->area.current ); if (!dfb_rectangle_region_intersects( &rect, &clip )) return DFB_OK; ret = dfb_surface_lock_buffer( dst_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock ); if (ret) return ret; if (!data->buf) { int cmptlut[3]; int width, height; int tlx, tly; int hs, vs; int i, j; bool direct, mono; if (jas_image_numcmpts(data->image) > 1) { cmptlut[0] = jas_image_getcmptbytype(data->image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R)); cmptlut[1] = jas_image_getcmptbytype(data->image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G)); cmptlut[2] = jas_image_getcmptbytype(data->image, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)); if (cmptlut[0] < 0 || cmptlut[1] < 0 || cmptlut[2] < 0) { dfb_surface_unlock_buffer( dst_surface, &lock ); return DFB_UNSUPPORTED; } mono = false; } else { cmptlut[0] = cmptlut[1] = cmptlut[2] = 0; mono = true; } width = jas_image_width(data->image); height = jas_image_height(data->image); tlx = jas_image_cmpttlx(data->image, 0); tly = jas_image_cmpttly(data->image, 0); hs = jas_image_cmpthstep(data->image, 0); vs = jas_image_cmptvstep(data->image, 0); data->buf = D_MALLOC( width*height*4 ); if (!data->buf) { dfb_surface_unlock_buffer( dst_surface, &lock ); return D_OOM(); } direct = (rect.w == width && rect.h == height && data->render_callback); #define GET_SAMPLE( n, x, y ) ({ \ int _s; \ _s = jas_image_readcmptsample(data->image, cmptlut[n], x, y); \ _s >>= jas_image_cmptprec(data->image, cmptlut[n]) - 8; \ if (_s > 255) \ _s = 255; \ else if (_s < 0) \ _s = 0; \ _s; \ }) for (i = 0; i < height; i++) { u32 *dst = data->buf + i * width; int x, y; y = (i - tly) / vs; if (y >= 0 && y < height) { for (j = 0; j < width; j++) { x = (j - tlx) / hs; if (x >= 0 && x < width) { unsigned int r, g, b; if (mono) { r = g = b = GET_SAMPLE(0, x, y); } else { r = GET_SAMPLE(0, x, y); g = GET_SAMPLE(1, x, y); b = GET_SAMPLE(2, x, y); } *dst++ = 0xff000000 | (r << 16) | (g << 8) | b; } else { *dst++ = 0; } } } else { memset( dst, 0, width*4 ); } if (direct) { DFBRectangle r = { rect.x, rect.y+i, width, 1 }; dfb_copy_buffer_32( data->buf + i*width, lock.addr, lock.pitch, &r, dst_surface, &clip ); if (data->render_callback) { r = (DFBRectangle) { 0, i, width, 1 }; cb_result = data->render_callback( &r, data->render_callback_ctx ); if (cb_result != DIRCR_OK) break; } } } if (!direct) { dfb_scale_linear_32( data->buf, width, height, lock.addr, lock.pitch, &rect, dst_surface, &clip ); if (data->render_callback) { DFBRectangle r = { 0, 0, width, height }; data->render_callback( &r, data->render_callback_ctx ); } } if (cb_result != DIRCR_OK) { D_FREE( data->buf ); data->buf = NULL; ret = DFB_INTERRUPTED; } } else { int width = jas_image_width(data->image); int height = jas_image_height(data->image); dfb_scale_linear_32( data->buf, width, height, lock.addr, lock.pitch, &rect, dst_surface, &clip ); if (data->render_callback) { DFBRectangle r = {0, 0, width, height}; data->render_callback( &r, data->render_callback_ctx ); } } dfb_surface_unlock_buffer( dst_surface, &lock ); return ret; }
void _fusion_call_process( FusionWorld *world, int call_id, FusionCallMessage *msg, void *ptr ) { FusionCallHandlerResult result = FCHR_RETURN; FusionCallHandler call_handler; FusionCallReturn call_ret = { .val = 0 }; D_DEBUG_AT( Fusion_Call, "%s( call_id %d, msg %p, ptr %p)\n", __FUNCTION__, call_id, msg, ptr ); D_MAGIC_ASSERT( world, FusionWorld ); D_ASSERT( msg != NULL ); D_ASSERT( msg->handler != NULL ); call_handler = msg->handler; if (direct_log_domain_check( &Fusion_Call )) // avoid call to direct_trace_lookup_symbol_at D_DEBUG_AT( Fusion_Call, " -> %s\n", direct_trace_lookup_symbol_at( call_handler ) ); result = call_handler( msg->caller, msg->call_arg, ptr ? ptr : msg->call_ptr, msg->ctx, msg->serial, &call_ret.val ); switch (result) { case FCHR_RETURN: if (msg->serial) { call_ret.serial = msg->serial; call_ret.call_id = call_id; while (ioctl (world->fusion_fd, FUSION_CALL_RETURN, &call_ret)) { switch (errno) { case EINTR: continue; case EIDRM: D_WARN( "caller withdrawn (signal?)" ); return; case EINVAL: D_ERROR( "Fusion/Call: invalid call\n" ); return; default: D_PERROR( "FUSION_CALL_RETURN" ); return; } } } break; case FCHR_RETAIN: break; default: D_BUG( "unknown result %d from call handler", result ); } } void _fusion_call_process3( FusionWorld *world, int call_id, FusionCallMessage3 *msg, void *ptr ) { FusionCallHandlerResult result = FCHR_RETURN; FusionCallHandler3 call_handler; FusionCallReturn3 call_ret; char *ret_ptr = NULL; unsigned int ret_length = 0; D_DEBUG_AT( Fusion_Call, "%s( call_id %d, msg %p, ptr %p)\n", __FUNCTION__, call_id, msg, ptr ); D_MAGIC_ASSERT( world, FusionWorld ); D_ASSERT( msg != NULL ); D_ASSERT( msg->handler != NULL ); call_handler = msg->handler; if (direct_log_domain_check( &Fusion_Call )) // avoid call to direct_trace_lookup_symbol_at D_DEBUG_AT( Fusion_Call, " -> %s\n", direct_trace_lookup_symbol_at( call_handler ) ); if (msg->ret_length > FUSION_CALL_RETURN_DATA_MAX) { D_ERROR( "Fusion/Call: Maximum return data length (%u) exceeded (%u)!\n", FUSION_CALL_RETURN_DATA_MAX, msg->ret_length ); } else { if (msg->ret_length > FUSION_CALL_RETURN_DATA_MAX_ON_STACK) { ret_ptr = D_MALLOC( msg->ret_length ); if (!ret_ptr) D_OOM(); } else ret_ptr = alloca( msg->ret_length ); } if (ret_ptr) result = call_handler( msg->caller, msg->call_arg, ptr ? ptr : msg->call_ptr, msg->call_length, msg->ctx, msg->serial, ret_ptr, msg->ret_length, &ret_length ); switch (result) { case FCHR_RETURN: if (msg->serial) { call_ret.call_id = call_id; call_ret.serial = msg->serial; call_ret.ptr = ret_ptr; call_ret.length = ret_length; while (ioctl (world->fusion_fd, FUSION_CALL_RETURN3, &call_ret)) { switch (errno) { case EINTR: continue; case EIDRM: D_DEBUG_AT( Fusion_Call, " -> caller withdrawn (signal?)\n" ); goto out; case EINVAL: D_ERROR( "Fusion/Call: invalid call\n" ); goto out; default: D_PERROR( "FUSION_CALL_RETURN3" ); goto out; } } } break; case FCHR_RETAIN: break; default: D_BUG( "unknown result %d from call handler", result ); } out: if (msg->ret_length > FUSION_CALL_RETURN_DATA_MAX_ON_STACK) D_FREE( ret_ptr ); }
static DFBResult driver_init_driver(CoreGraphicsDevice *device, GraphicsDeviceFuncs *funcs, void *driver_data, void *device_data, CoreDFB *core) { SiSDriverData *drv = (SiSDriverData *)driver_data; FBDev *dfb_fbdev; struct sisfb_info *fbinfo; u32 fbinfo_size; u32 zero = 0; (void)device_data; dfb_fbdev = dfb_system_data(); if (!dfb_fbdev) return DFB_IO; if (ioctl(dfb_fbdev->fd, SISFB_GET_INFO_SIZE, &fbinfo_size) == 0) { fbinfo = D_MALLOC(fbinfo_size); drv->get_info = SISFB_GET_INFO | (fbinfo_size << 16); drv->get_automaximize = SISFB_GET_AUTOMAXIMIZE; drv->set_automaximize = SISFB_SET_AUTOMAXIMIZE; } else { fbinfo = D_MALLOC(sizeof(struct sisfb_info)); drv->get_info = SISFB_GET_INFO_OLD; drv->get_automaximize = SISFB_GET_AUTOMAXIMIZE_OLD; drv->set_automaximize = SISFB_SET_AUTOMAXIMIZE_OLD; } if (fbinfo == NULL) return DFB_NOSYSTEMMEMORY; if (ioctl(dfb_fbdev->fd, drv->get_info, fbinfo) == -1) { D_FREE(fbinfo); return DFB_IO; } check_sisfb_version(drv, fbinfo); D_FREE(fbinfo); if (drv->has_auto_maximize) { if (ioctl(dfb_fbdev->fd, drv->get_automaximize, &drv->auto_maximize)) return DFB_IO; if (drv->auto_maximize) if (ioctl(dfb_fbdev->fd, drv->set_automaximize, &zero)) return DFB_IO; } drv->mmio_base = dfb_gfxcard_map_mmio(device, 0, -1); if (!drv->mmio_base) return DFB_IO; /* base functions */ funcs->EngineSync = sis_engine_sync; funcs->CheckState = sis_check_state; funcs->SetState = sis_set_state; /* drawing functions */ funcs->FillRectangle = sis_fill_rectangle; funcs->DrawRectangle = sis_draw_rectangle; funcs->DrawLine = sis_draw_line; /* blitting functions */ funcs->Blit = sis_blit; funcs->StretchBlit = sis_stretchblit; /* allocate buffer for stretchBlit with colorkey */ drv->buffer_offset = dfb_gfxcard_reserve_memory( device, 1024*768*4 ); return DFB_OK; }
DFBResult IDirectFBFont_CreateFromBuffer( IDirectFBDataBuffer *buffer, CoreDFB *core, const DFBFontDescription *desc, IDirectFBFont **interface ) { DFBResult ret; DirectInterfaceFuncs *funcs = NULL; IDirectFBDataBuffer_data *buffer_data; IDirectFBFont *ifont; IDirectFBFont_ProbeContext ctx = {0}; /* Get the private information of the data buffer. */ buffer_data = (IDirectFBDataBuffer_data*) buffer->priv; if (!buffer_data) return DFB_DEAD; /* Provide a fallback for image providers without data buffer support. */ ctx.filename = buffer_data->filename; /* try to map the "file" content first */ if (try_map_file( buffer_data, &ctx ) != DFB_OK) { /* try to load the "file" content from the buffer */ /* we need to be able to seek (this implies non-streamed, so we also know the size) so we can reuse the buffer */ if (buffer->SeekTo( buffer, 0 ) == DFB_OK) { unsigned int size, got; /* get the "file" length */ buffer->GetLength( buffer, &size ); ctx.content = D_MALLOC( size ); if (!ctx.content) return DR_NOLOCALMEMORY; ctx.content_size = 0; while (ctx.content_size < size) { unsigned int get = size - ctx.content_size; if (get > 8192) get = 8192; ret = buffer->WaitForData( buffer, get ); if (ret) { D_DERROR( ret, "%s: WaitForData failed!\n", __FUNCTION__ ); break; } ret = buffer->GetData( buffer, get, ctx.content + ctx.content_size, &got ); if (ret) { D_DERROR( ret, "%s: GetData failed!\n", __FUNCTION__ ); break; } if (!got) break; ctx.content_size += got; } if (ctx.content_size != size) { D_ERROR( "%s: Got size %u differs from supposed %u!\n", __FUNCTION__, ctx.content_size, size ); D_FREE( ctx.content ); return DFB_FAILURE; } } } /* Find a suitable implementation. */ ret = DirectGetInterface( &funcs, "IDirectFBFont", NULL, DirectProbeInterface, &ctx ); if (ret) { unmap_or_free( &ctx ); return ret; } DIRECT_ALLOCATE_INTERFACE( ifont, IDirectFBFont ); /* Construct the interface. */ ret = funcs->Construct( ifont, core, &ctx, desc ); if (ret) { unmap_or_free( &ctx ); return ret; } /* store pointer for deletion at destroy */ { IDirectFBFont_data *data = (IDirectFBFont_data*)(ifont->priv); data->content = ctx.content; data->content_size = ctx.content_size; data->content_mapped = ctx.content_mapped; } *interface = ifont; return DFB_OK; }
int main( int argc, char *argv[] ) { int i; DirectResult ret; DirectLogType log_type = DLT_STDERR; const char *log_param = NULL; DirectLog *log; for (i=1; i<argc; i++) { if (!strcmp( argv[i], "-f" )) { if (++i < argc) { log_type = DLT_FILE; log_param = argv[i]; } else return show_usage(argv[0]); } else if (!strcmp( argv[i], "-u" )) { if (++i < argc) { log_type = DLT_UDP; log_param = argv[i]; } else return show_usage(argv[0]); } else return show_usage(argv[0]); } /* Initialize logging. */ ret = direct_log_create( log_type, log_param, &log ); if (ret) return -1; /* Set default log to use. */ direct_log_set_default( log ); /* Test memory leak detector by not freeing this one. */ D_MALLOC( 1351 ); D_INFO( "Direct/Test: Application starting...\n" ); /* Initialize libdirect. */ direct_initialize(); D_INFO( "Direct/Test: Application stopping...\n" ); /* Shutdown libdirect. */ direct_shutdown(); D_INFO( "Direct/Test: You should see a leak message with debug-mem turned on...\n" ); /* Shutdown logging. */ direct_log_destroy( log ); direct_config->debug = true; direct_print_memleaks(); return 0; }
static void handle_request( VoodooManager *manager, VoodooRequestMessage *request ) { DirectResult ret; VoodooInstance *instance; D_MAGIC_ASSERT( manager, VoodooManager ); D_ASSERT( request != NULL ); D_ASSERT( request->header.size >= sizeof(VoodooRequestMessage) ); D_ASSERT( request->header.type == VMSG_REQUEST ); D_DEBUG( "Voodoo/Dispatch: Handling REQUEST message %llu to %u::%u %s%s(%d bytes).\n", (unsigned long long)request->header.serial, request->instance, request->method, (request->flags & VREQ_RESPOND) ? "[RESPONDING] " : "", (request->flags & VREQ_ASYNC) ? "[ASYNC] " : "", request->header.size ); pthread_mutex_lock( &manager->instances.lock ); instance = direct_hash_lookup( manager->instances.local, request->instance ); if (!instance) { pthread_mutex_unlock( &manager->instances.lock ); D_ERROR( "Voodoo/Dispatch: " "Requested instance %u doesn't exist (anymore)!\n", request->instance ); if (request->flags & VREQ_RESPOND) voodoo_manager_respond( manager, request->header.serial, DR_NOSUCHINSTANCE, VOODOO_INSTANCE_NONE, VMBT_NONE ); return; } if (request->flags & VREQ_ASYNC) { pthread_t thread; DispatchAsyncContext *context; context = D_MALLOC( sizeof(DispatchAsyncContext) + request->header.size ); if (!context) { D_WARN( "out of memory" ); pthread_mutex_unlock( &manager->instances.lock ); return; } context->manager = manager; context->instance = instance; context->request = (VoodooRequestMessage*) (context + 1); direct_memcpy( context->request, request, request->header.size ); pthread_create( &thread, NULL, dispatch_async_thread, context ); pthread_detach( thread ); } else { ret = instance->dispatch( instance->proxy, instance->real, manager, request ); if (ret && (request->flags & VREQ_RESPOND)) voodoo_manager_respond( manager, request->header.serial, ret, VOODOO_INSTANCE_NONE, VMBT_NONE ); } pthread_mutex_unlock( &manager->instances.lock ); }