Beispiel #1
0
DirectResult
voodoo_client_create( const char     *host,
                      int             port,
                      VoodooClient  **ret_client )
{
     DirectResult    ret;
     VoodooPlayInfo  info;
     VoodooClient   *client;
     VoodooPlayer   *player;
     char            buf[100] = { 0 };
     const char     *hostname = host;
     bool            raw = true;

     D_ASSERT( ret_client != NULL );

     if (!host)
          host = "";

     if (!port)
          port = 2323;

     D_DEBUG_AT( Voodoo_Client, "%s( '%s', %d )\n", __FUNCTION__, host, port );

     if (port != 2323) {
          D_DEBUG_AT( Voodoo_Client, "  -> port != 2323, using PACKET mode right away\n" );

          raw = false;
     }

     direct_list_foreach (client, m_clients) {
          if (!strcmp( client->host, host ) && client->port == port) {
               D_INFO( "Voodoo/Client: Reconnecting to '%s', increasing ref count of existing connection!\n", host );

               client->refs++;

               *ret_client = client;

               return DR_OK;
          }
     }

     /*
      * Get the player singleton
      */
     ret = voodoo_player_create( NULL, &player );
     if (ret) {
          D_DERROR( ret, "Voodoo/Client: Could not create the player!\n" );
          return ret;
     }

     /*
      * If we got a hostname or address try to lookup the player info
      */
     // FIXME: resolve first, not late in voodoo_link_init_connect
     if (hostname && hostname[0]) {
          ret = voodoo_player_lookup_by_address( player, hostname, &info );
          if (ret == DR_OK) {
               if (info.flags & VPIF_PACKET)
                    raw = false;
          }
     }
     else {
          /*
           * Start discovery and use first host visible
           */
          ret = discover_host( player, NULL, &info, buf, sizeof(buf) );
          if (ret == DR_OK) {
               if (info.flags & VPIF_PACKET)
                    raw = false;

               hostname = buf;
          }
     }

     if (!hostname || !hostname[0]) {
          D_ERROR( "Voodoo/Client: Did not find any other player!\n" );
          return DR_ITEMNOTFOUND;
     }


     /* Allocate client structure. */
     client = D_CALLOC( 1, sizeof(VoodooClient) );
     if (!client)
          return D_OOM();


     raw = !voodoo_config->link_packet && (voodoo_config->link_raw || raw);

     /* Create a link to the other player. */
     ret = voodoo_link_init_connect( &client->vl, hostname, port, raw );
     if (ret) {
          D_DERROR( ret, "Voodoo/Client: Failed to initialize Voodoo Link!\n" );
          D_FREE( client );
          return ret;
     }

     D_INFO( "Voodoo/Client: Fetching player information...\n" );

     if (raw) {     // FIXME: send_discover_and_receive_info() only does RAW, but we don't need it for packet connection, yet
          VoodooPlayVersion version;
          VoodooPlayInfo    info;

          ret = send_discover_and_receive_info( &client->vl, &version, &info );
          if (ret) {
               D_DEBUG_AT( Voodoo_Client, "  -> Failed to receive player info via TCP!\n" );

               D_INFO( "Voodoo/Client: No player information from '%s', trying to discover via UDP!\n", host );

               /*
                * Fallback to UDP discovery
                */
               ret = discover_host( player, hostname, &info, buf, sizeof(buf) );
               if (ret == DR_OK) {
                    if (info.flags & VPIF_PACKET)
                         raw = false;
               }
          }
          else {
               D_INFO( "Voodoo/Client: Connected to '%s' (%-15s) %s "
                       "=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x= "
                       "(vendor: %s, model: %s)\n",
                       info.name, host,
                       (info.flags & VPIF_LEVEL2) ? "*" : " ",
                       info.uuid[0], info.uuid[1], info.uuid[2], info.uuid[3], info.uuid[4],
                       info.uuid[5], info.uuid[6], info.uuid[7], info.uuid[8], info.uuid[9],
                       info.uuid[10], info.uuid[11], info.uuid[12], info.uuid[13], info.uuid[14],
                       info.uuid[15],
                       info.vendor, info.model );

               if (raw && !voodoo_config->link_raw) {
                    /*
                     * Switch to packet mode?
                     */
                    if (info.flags & VPIF_PACKET)
                         raw = false;
               }
          }

          /*
           * Switch to packet mode?
           */
          if (!raw) {
               D_INFO( "Voodoo/Client: Switching to packet mode!\n" );

               client->vl.Close( &client->vl );

               /* Create another link to the other player. */
               ret = voodoo_link_init_connect( &client->vl, hostname, port, false );
               if (ret) {
                    D_DERROR( ret, "Voodoo/Client: Failed to initialize second Voodoo Link!\n" );
                    D_FREE( client );
                    return ret;
               }
          }
     }


     /* Create the manager. */
     ret = voodoo_manager_create( &client->vl, client, NULL, &client->manager );
     if (ret) {
          client->vl.Close( &client->vl );
          D_FREE( client );
          return ret;
     }

     client->refs = 1;
     client->host = D_STRDUP( host );
     client->port = port;

     direct_list_prepend( &m_clients, &client->link );

     /* Return the new client. */
     *ret_client = client;

     D_DEBUG_AT( Voodoo_Client, "  => client %p\n", client );

     return DR_OK;
}
Beispiel #2
0
int
main( int argc, char *argv[] )
{
     DirectResult   ret;
     pid_t          child_pid;
     TestMessage    message = {0};
     FusionReactor *reactor;
     Reaction       reaction;
     FusionCall     call;

     DirectFBInit( &argc, &argv );

     ret = fusion_enter( -1, 0, FER_MASTER, &m_world );
     if (ret) {
          D_DERROR( ret, "fusion_enter() failed" );
          return ret;
     }

     MSG( "Entered world %d as master (FusionID %lu, pid %d)\n",
          fusion_world_index( m_world ), fusion_id( m_world ), getpid() );


     reactor = fusion_reactor_new( sizeof(TestMessage), "Test", m_world );
     if (!reactor) {
          D_ERROR( "fusion_reactor_new() failed\n" );
          return -1;
     }


     MSG( "Attaching to reactor...\n" );

     ret = fusion_reactor_attach( reactor, reaction_callback, NULL, &reaction );
     if (ret) {
          D_DERROR( ret, "fusion_reactor_attach() failed" );
          return ret;
     }


     MSG( ".........FORKING NOW.........\n" );

     fusion_world_set_fork_action( m_world, FFA_FORK );
     child_pid = fork();
     fusion_world_set_fork_action( m_world, FFA_CLOSE );

     switch (child_pid) {
          case -1:
               D_PERROR( "fork() failed" );
               break;

          case 0:
               setsid();
               MSG( "...arrived after fork() in child (pid %d)..\n", getpid() );
               MSG( "..child (FusionID %lu).\n", fusion_id( m_world ) );
               usleep( 400000 );
               break;

          default:
               usleep( 100000 );
               MSG( "...returned from fork() in parent, child pid %d.\n", child_pid );

               MSG( "Initializing dispatch callback...\n" );

               ret = fusion_call_init( &call, dispatch_callback, NULL, m_world );
               if (ret) {
                    D_DERROR( ret, "fusion_call_init() failed" );
                    return ret;
               }

               MSG( "Setting dispatch callback...\n" );

               ret = fusion_reactor_set_dispatch_callback( reactor, &call, NULL );
               if (ret) {
                    D_DERROR( ret, "fusion_reactor_set_dispatch_callback() failed" );
                    return ret;
               }


               MSG( "Sending message via reactor...\n" );
               fusion_reactor_dispatch( reactor, &message, true, NULL );

               usleep( 100000 );

               MSG( "Destroying reactor...\n" );
               fusion_reactor_destroy( reactor );
               MSG( "...destroyed reactor!\n" );

               usleep( 400000 );

               MSG( "Freeing reactor...\n" );
               fusion_reactor_free( reactor );
               MSG( "...freed reactor!\n" );

               break;
     }



     MSG( "Exiting from world %d (FusionID %lu, pid %d)...\n",
          fusion_world_index( m_world ), fusion_id( m_world ), getpid() );

     fusion_exit( m_world, false );

     return 0;
}
Beispiel #3
0
Bool
dfb_x11_open_window( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format )
{
     XWindow              *xw;
     XSetWindowAttributes  attr = { .background_pixmap = 0 };
     void                 *old_error_handler = 0;
     unsigned int          cw_mask = CWEventMask;

     D_DEBUG_AT( X11_Window, "Creating %4dx%4d %s window...\n", iWidth, iHeight, dfb_pixelformat_name(format) );

     xw = D_CALLOC( 1, sizeof(XWindow) );
     if (!xw)
          return D_OOM();

     /* We set the structure as needed for our window */
     xw->width   = iWidth;
     xw->height  = iHeight;
     xw->display = x11->display;

     xw->screenptr = DefaultScreenOfDisplay(xw->display);
     xw->screennum = DefaultScreen(xw->display);
     xw->depth     = DefaultDepthOfScreen(xw->screenptr);
     xw->visual    = DefaultVisualOfScreen(xw->screenptr);

     attr.event_mask =
            ButtonPressMask
          | ButtonReleaseMask
          | PointerMotionMask
          | KeyPressMask
          | KeyReleaseMask
          | ExposureMask
          | StructureNotifyMask;

     if (dfb_config->x11_borderless) {
          attr.override_redirect = True;

          cw_mask |= CWOverrideRedirect;
     }

     XLockDisplay( x11->display );

     old_error_handler = XSetErrorHandler( error_handler );

     error_code = 0;

     xw->window = XCreateWindow( xw->display,
                                 RootWindowOfScreen(xw->screenptr),
                                 iXPos, iYPos, iWidth, iHeight, 0, xw->depth, InputOutput,
                                 xw->visual, cw_mask, &attr );
     XSync( xw->display, False );
     if (!xw->window || error_code) {
          D_FREE( xw );
          XUnlockDisplay( x11->display );
          return False;
     }


     XSizeHints Hints;

     /*
      * Here we inform the function of what we are going to change for the
      * window (there's also PPosition but it's obsolete)
      */
     Hints.flags    =    PSize | PMinSize | PMaxSize;

     /*
      * Now we set the structure to the values we need for width & height.
      * For esthetic reasons we set Width=MinWidth=MaxWidth.
      * The same goes for Height. You can try whith differents values, or
      * let's use Hints.flags=Psize; and resize your window..
      */
     Hints.min_width          =    Hints.max_width          =    Hints.base_width    =    xw->width;
     Hints.min_height    =    Hints.max_height    =    Hints.base_height   =    xw->height;

     /* Now we can set the size hints for the specified window */
     XSetWMNormalHints(xw->display,xw->window,&Hints);

     /* We change the title of the window (default:Untitled) */
     XStoreName(xw->display,xw->window,"DFB X11 system window");

     xw->gc = XCreateGC(xw->display, xw->window, 0, NULL);

#if 0
     // Create a null cursor
     Pixmap  pixmp1;
     Pixmap  pixmp2;
     XColor  fore;
     XColor  back;
     char    zero = 0;

     pixmp1 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 );
     pixmp2 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 );

     xw->NullCursor = XCreatePixmapCursor( xw->display, pixmp1, pixmp2, &fore, &back, 0, 0 );

     XFreePixmap ( xw->display, pixmp1 );
     XFreePixmap ( xw->display, pixmp2 );

     XDefineCursor( xw->display, xw->window, xw->NullCursor );
#endif

     /* maps the window and raises it to the top of the stack */
     XMapRaised( xw->display, xw->window );


     if (x11->use_shm) {
          // Shared memory
          xw->shmseginfo=(XShmSegmentInfo *)D_CALLOC(1, sizeof(XShmSegmentInfo));
          if (!xw->shmseginfo) {
               x11->use_shm = false;
               goto no_shm;
          }

          xw->ximage=XShmCreateImage(xw->display, xw->visual, xw->depth, ZPixmap,
                                     NULL,xw->shmseginfo, xw->width, xw->height * 2);
          XSync( xw->display, False );
          if (!xw->ximage || error_code) {
               D_ERROR("X11: Error creating shared image (XShmCreateImage) \n");
               x11->use_shm = false;
               D_FREE(xw->shmseginfo);
               error_code = 0;
               goto no_shm;
          }

          xw->bpp = (xw->ximage->bits_per_pixel + 7) / 8;

          /* we firstly create our shared memory segment with the size we need, and
          correct permissions for the owner, the group and the world --> 0777 */
          xw->shmseginfo->shmid=shmget(IPC_PRIVATE,
                                       xw->ximage->bytes_per_line * xw->ximage->height * 2,
                                       IPC_CREAT|0777);

          if (xw->shmseginfo->shmid<0) {
               x11->use_shm = false;
               XDestroyImage(xw->ximage);
               D_FREE(xw->shmseginfo);
               goto no_shm;
          }

          /* Then, we have to attach the segment to our process, and we let the
          function search the correct memory place --> NULL. It's safest ! */
          xw->shmseginfo->shmaddr = shmat( xw->shmseginfo->shmid, NULL, 0 );
          if (!xw->shmseginfo->shmaddr) {
               x11->use_shm = false;
               shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
               XDestroyImage(xw->ximage);
               D_FREE(xw->shmseginfo);
               goto no_shm;
          }

          /* We set the buffer in Read and Write mode */
          xw->shmseginfo->readOnly=False;

          xw->virtualscreen= xw->ximage->data = xw->shmseginfo->shmaddr;


          XSetErrorHandler( error_handler_shm );

          XShmAttach(x11->display,xw->shmseginfo);

          XShmPutImage(x11->display, xw->window, xw->gc, xw->ximage,
                       0, 0, 0, 0, 1, 1, False);

          XSync(x11->display, False);

          XSetErrorHandler( error_handler );

          if (!x11->use_shm) {
               shmdt(xw->shmseginfo->shmaddr);
               shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL);
               XDestroyImage(xw->ximage);
               D_FREE(xw->shmseginfo);
          }
     }

no_shm:
     if (!x11->use_shm) {
          int pitch;

          xw->bpp = (xw->depth > 16) ? 4 :
                    (xw->depth >  8) ? 2 : 1;

          pitch = (xw->bpp * xw->width + 3) & ~3;

          /* Use malloc(), not D_MALLOC() here, because XCreateImage()
           * will call free() on this data.
           */
          xw->virtualscreen = malloc ( 2 * xw->height * pitch );

          xw->ximage = XCreateImage( xw->display, xw->visual, xw->depth, ZPixmap, 0,
                                     xw->virtualscreen, xw->width, xw->height * 2, 32, pitch );
          XSync( xw->display, False );
          if (!xw->ximage || error_code) {
               D_ERROR( "X11/Window: XCreateImage( Visual %02lu, depth %d, size %dx%d, buffer %p [%d] ) failed!\n",
                        xw->visual->visualid, xw->depth, xw->width, xw->height * 2, xw->virtualscreen, pitch );
               XFreeGC(xw->display,xw->gc);
               XDestroyWindow(xw->display,xw->window);
               XSetErrorHandler( old_error_handler );
               XUnlockDisplay( x11->display );
               D_FREE( xw );
               return False;
          }
     }

     XSetErrorHandler( old_error_handler );

     XUnlockDisplay( x11->display );

     D_INFO( "X11/Display: %ssing XShm.\n", x11->use_shm ? "U" : "Not u" );

     (*ppXW) = xw;

     return True;
}

void
dfb_x11_close_window( DFBX11 *x11, XWindow* xw )
{
     if (x11->use_shm) {
          XShmDetach( xw->display, xw->shmseginfo );
          shmdt( xw->shmseginfo->shmaddr );
          shmctl( xw->shmseginfo->shmid, IPC_RMID, NULL );
          D_FREE( xw->shmseginfo );
     }

     XDestroyImage( xw->ximage );

     XFreeGC( xw->display, xw->gc );
     XDestroyWindow( xw->display, xw->window );
#if 0
     XFreeCursor( xw->display, xw->NullCursor );
#endif

     D_FREE( xw );
}
Beispiel #4
0
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;
}
DirectResult
voodoo_link_init_connect( VoodooLink *link,
                          const char *hostname,
                          int         port,
                          bool        raw )
{
     DirectResult     ret;
     int              err;
     struct addrinfo  hints;
     struct addrinfo *addr;
     char             portstr[10];
     Link            *l;


     memset( &hints, 0, sizeof(hints) );
     hints.ai_flags    = AI_CANONNAME;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_family   = PF_UNSPEC;

     D_INFO( "Voodoo/Link: Looking up host '%s'...\n", hostname );

     snprintf( portstr, sizeof(portstr), "%d", port );

     err = getaddrinfo( hostname, portstr, &hints, &addr );
     if (err) {
          switch (err) {
               case EAI_FAMILY:
                    D_ERROR( "Direct/Log: Unsupported address family!\n" );
                    return DR_UNSUPPORTED;

               case EAI_SOCKTYPE:
                    D_ERROR( "Direct/Log: Unsupported socket type!\n" );
                    return DR_UNSUPPORTED;

               case EAI_NONAME:
                    D_ERROR( "Direct/Log: Host not found!\n" );
                    return DR_FAILURE;

               case EAI_SERVICE:
                    D_ERROR( "Direct/Log: Service is unreachable!\n" );
                    return DR_FAILURE;

#ifdef EAI_ADDRFAMILY
               case EAI_ADDRFAMILY:
#endif
               case EAI_NODATA:
                    D_ERROR( "Direct/Log: Host found, but has no address!\n" );
                    return DR_FAILURE;

               case EAI_MEMORY:
                    return D_OOM();

               case EAI_FAIL:
                    D_ERROR( "Direct/Log: A non-recoverable name server error occurred!\n" );
                    return DR_FAILURE;

               case EAI_AGAIN:
                    D_ERROR( "Direct/Log: Temporary error, try again!\n" );
                    return DR_TEMPUNAVAIL;

               default:
                    D_ERROR( "Direct/Log: Unknown error occured!?\n" );
                    return DR_FAILURE;
          }
     }


     l = D_CALLOC( 1, sizeof(Link) );
     if (!l)
          return D_OOM();

     /* Create the client socket. */
     l->fd[0] = socket( addr->ai_family, SOCK_STREAM, 0 );
     if (l->fd[0] < 0) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
          freeaddrinfo( addr );
          D_FREE( l );
          return ret;
     }
     l->fd[1] = l->fd[0];

#if !VOODOO_BUILD_NO_SETSOCKOPT
     if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );

     if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
#endif

     D_INFO( "Voodoo/Link: Connecting to '%s:%d'...\n", addr->ai_canonname, port );

     /* Connect to the server. */
     err = connect( l->fd[0], addr->ai_addr, addr->ai_addrlen );
     freeaddrinfo( addr );

     if (err) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
          close( l->fd[0] );
          D_FREE( l );
          return ret;
     }

     D_INFO( "Voodoo/Link: Connected.\n" );

     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );

     if (!raw) {
          link->code = 0x80008676;

          if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
               D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
               close( l->fd[0] );
               D_FREE( l );
               return DR_IO;
          }
     }
     D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );

     if (pipe( l->wakeup_fds ))
          return errno2result( errno );


     link->priv        = l;
     link->Close       = Close;
     link->Read        = Read;
     link->Write       = Write;
     link->SendReceive = SendReceive;
     link->WakeUp      = WakeUp;
     link->WaitForData = WaitForData;

     return DR_OK;
}
Beispiel #6
0
int
smd_nvme_list_streams(uint32_t *nr, struct smd_nvme_stream_bond *streams,
		      daos_anchor_t *anchor)
{
	struct smd_store	*store = get_smd_store();
	daos_anchor_t		*probe_hash = NULL;
	dbtree_probe_opc_t	opc;
	daos_handle_t		sti_hdl;
	int			i = 0;
	int			rc = 0;

	D_DEBUG(DB_TRACE, "listing the stream table\n");
	if (streams == NULL || nr == NULL) {
		D_ERROR("Streams array or NR cannot be NULL\n");
		return -DER_INVAL;
	}

	smd_lock(SMD_STAB_LOCK);
	rc = dbtree_iter_prepare(store->sms_stream_tab, 0, &sti_hdl);
	if (rc)
		D_GOTO(out, rc);

	if (anchor != NULL &&  !daos_anchor_is_zero(anchor))
		probe_hash = anchor;

	opc = probe_hash == NULL ? BTR_PROBE_FIRST : BTR_PROBE_GT;
	rc = dbtree_iter_probe(sti_hdl, opc, DAOS_INTENT_DEFAULT, NULL, anchor);
	if (rc != 0)
		D_GOTO(out_eof, rc);

	i = 0;
	while (i < *nr) {
		daos_iov_t	key, value;
		int		stream_id;

		daos_iov_set(&key, &stream_id, sizeof(stream_id));
		daos_iov_set(&value, &streams[i],
			     sizeof(struct smd_nvme_stream_bond));
		rc = dbtree_iter_fetch(sti_hdl, &key, &value, anchor);
		if (rc != 0) {
			D_ERROR("Error while fetching stream info: %d\n", rc);
			break;
		}
		i++;

		rc = dbtree_iter_next(sti_hdl);
		if (rc) {
			if (rc != -DER_NONEXIST)
				D_ERROR("Failed to iterate next: %d\n", rc);
			break;
		}
	}

out_eof:
	*nr = i;
	if (rc == -DER_NONEXIST) {
		anchor ? daos_anchor_set_eof(anchor) : NULL;
		rc = 0;
	}
	dbtree_iter_finish(sti_hdl);
out:
	smd_unlock(SMD_STAB_LOCK);
	return rc;
}
Beispiel #7
0
DirectResult
fusion_shm_pool_create( FusionWorld          *world,
                        const char           *name,
                        unsigned int          max_size,
                        bool                  debug,
                        FusionSHMPoolShared **ret_pool )
{
     int              i;
     DirectResult     ret;
     FusionSHM       *shm;
     FusionSHMShared *shared;

     D_MAGIC_ASSERT( world, FusionWorld );
     D_MAGIC_ASSERT( world->shared, FusionWorldShared );
     D_ASSERT( name != NULL );
     D_ASSERT( max_size > 0 );
     D_ASSERT( ret_pool != NULL );

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p [%d], '%s', %d, %p, %sdebug )\n", __FUNCTION__,
                 world, world->shared->world_index, name, max_size, ret_pool, debug ? "" : "non-" );

#if !DIRECT_BUILD_DEBUGS
     debug = false;
#endif

     shm = &world->shm;

     D_MAGIC_ASSERT( shm, FusionSHM );

     shared = shm->shared;

     D_MAGIC_ASSERT( shared, FusionSHMShared );

     if (max_size < 8192) {
          D_ERROR( "Fusion/SHMPool: Maximum size (%d) should be 8192 at least!\n", max_size );
          return DR_INVARG;
     }

     ret = fusion_skirmish_prevail( &shared->lock );
     if (ret)
          goto error;

     if (shared->num_pools == FUSION_SHM_MAX_POOLS) {
          D_ERROR( "Fusion/SHMPool: Maximum number of pools (%d) already reached!\n", FUSION_SHM_MAX_POOLS );
          ret = DR_LIMITEXCEEDED;
          goto error;
     }

     for (i=0; i<FUSION_SHM_MAX_POOLS; i++) {
          if (!shared->pools[i].active)
               break;

          D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );
          D_MAGIC_ASSUME( &shm->pools[i], FusionSHMPool );
     }

     D_ASSERT( i < FUSION_SHM_MAX_POOLS );

     D_DEBUG_AT( Fusion_SHMPool, "  -> index %d\n", i );

     memset( &shm->pools[i], 0, sizeof(FusionSHMPool) );
     memset( &shared->pools[i], 0, sizeof(FusionSHMPoolShared) );

     shared->pools[i].index = i;

     ret = init_pool( shm, &shm->pools[i], &shared->pools[i], name, max_size, debug );
     if (ret)
          goto error;

     shared->num_pools++;

     fusion_skirmish_dismiss( &shared->lock );

     *ret_pool = &shared->pools[i];

     D_DEBUG_AT( Fusion_SHMPool, "  -> %p\n", *ret_pool );

     return DR_OK;


error:
     fusion_skirmish_dismiss( &shared->lock );

     return ret;
}
Beispiel #8
0
static int
parse_cmdline( int argc, char *argv[] )
{
     int   i;
     char *end;

     for (i=1; i<argc; i++) {
          if (!strcmp( argv[i], "-s" )) {
               if (++i < argc) {
                    block_size = strtoul( argv[i], &end, 10 );

                    if (end && *end) {
                         D_ERROR( "Parse error in number '%s'!\n", argv[i] );
                         return -1;
                    }

                    if (block_size < 1)
                         return show_usage();
               }
               else
                    return show_usage();
          }
          else if (!strcmp( argv[i], "-b" )) {
               if (++i < argc) {
                    bit_rate = strtoul( argv[i], &end, 10 );

                    if (end && *end) {
                         D_ERROR( "Parse error in number '%s'!\n", argv[i] );
                         return -1;
                    }
               }
               else
                    return show_usage();
          }
          else if (!strcmp( argv[i], "-B" )) {
               if (++i < argc) {
                    bit_rate = strtoul( argv[i], &end, 10 ) * 1024;

                    if (end && *end) {
                         D_ERROR( "Parse error in number '%s'!\n", argv[i] );
                         return -1;
                    }
               }
               else
                    return show_usage();
          }
          else if (!strcmp( argv[i], "-c" )) {
               run_busy = 1;
          }
          else if (!strcmp( argv[i], "-f" )) {
               do_fork = 1;
          }
          else if (!strcmp( argv[i], "-t" )) {
               do_thread = 1;
          }
          else
               return show_usage();
     }

     return 0;
}
Beispiel #9
0
DirectResult
fusion_shm_init( FusionWorld *world )
{
     int              i;
     int              num;
     DirectResult     ret;
     FusionSHM       *shm;
     FusionSHMShared *shared;

     D_MAGIC_ASSERT( world, FusionWorld );
     D_MAGIC_ASSERT( world->shared, FusionWorldShared );

     shm    = &world->shm;
     shared = &world->shared->shm;

     /* Initialize local data. */
     memset( shm, 0, sizeof(FusionSHM) );

     shm->world  = world;
     shm->shared = shared;

     /* Initialize shared data. */
     if (fusion_master( world )) {
          memset( shared, 0, sizeof(FusionSHMShared) );

          if (fusion_config->tmpfs) {
               snprintf( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN, fusion_config->tmpfs );
          }
          else if (!find_tmpfs( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN )) {
               D_ERROR( "Fusion/SHM: Could not find tmpfs mount point, falling back to /dev/shm!\n" );
               snprintf( shared->tmpfs, FUSION_SHM_TMPFS_PATH_NAME_LEN, "/dev/shm" );
          }

          shared->world = world->shared;

          /* Initialize shared lock. */
          ret = fusion_skirmish_init( &shared->lock, "Fusion SHM", world );
          if (ret) {
               D_DERROR( ret, "Fusion/SHM: Failed to create skirmish!\n" );
               return ret;
          }

          /* Initialize static pool array. */
          for (i=0; i<FUSION_SHM_MAX_POOLS; i++)
               shared->pools[i].index = i;

          D_MAGIC_SET( shm, FusionSHM );
          D_MAGIC_SET( shared, FusionSHMShared );
     }
     else {
          D_MAGIC_ASSERT( shared, FusionSHMShared );

          ret = fusion_skirmish_prevail( &shared->lock );
          if (ret)
               return ret;

          D_MAGIC_SET( shm, FusionSHM );

          for (i=0, num=0; i<FUSION_SHM_MAX_POOLS; i++) {
               if (shared->pools[i].active) {
                    D_MAGIC_ASSERT( &shared->pools[i], FusionSHMPoolShared );

                    ret = fusion_shm_pool_attach( shm, &shared->pools[i] );
                    if (ret) {
                         for (--i; i>=0; i--) {
                              if (shared->pools[i].active)
                                   fusion_shm_pool_detach( shm, &shared->pools[i] );
                         }

                         fusion_skirmish_dismiss( &shared->lock );

                         D_MAGIC_CLEAR( shm );

                         return ret;
                    }

                    num++;
               }
          }

          D_ASSERT( num == shared->num_pools );

          fusion_skirmish_dismiss( &shared->lock );
     }

     return DR_OK;
}
static DFBResult
IDirectFBImageProvider_WebP_RenderTo( IDirectFBImageProvider *thiz,
                                      IDirectFBSurface       *destination,
                                      const DFBRectangle     *dest_rect )
{
     DFBResult               ret;

     DFBRegion               clip;
     CoreSurface            *dst_surface;
     CardState               state;

     CoreSurfaceBufferLock   lock;

     IDirectFBSurface_data  *dst_data;
     DIRenderCallbackResult  cb_result = DIRCR_OK;

     DFBRectangle           src_rect;
     DFBRectangle           rect;

     DIRECT_INTERFACE_GET_DATA( IDirectFBImageProvider_WebP )

     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_create_simple( data->base.core, data->width, data->height, data->pixelformat,
                                      DSCS_RGB, DSCAPS_NONE, CSTF_NONE,
                                      0, NULL, &data->decode_surface );
     if (ret) {
          D_ERROR( "Failed to create surface : '%s'\n", DirectResultString(ret) );
          goto error;
     }

     ret = dfb_surface_lock_buffer( data->decode_surface, CSBR_BACK, CSAID_CPU, CSAF_WRITE, &lock );
     if (ret) {
          D_ERROR( "Failed to lock the surface : '%s'\n", DirectResultString(ret) );
          goto error;
     }

     ret = WebP_decode_image( data, &lock );
     if (ret) {
          D_ERROR( "Failed to decode the image : '%s'\n", DirectResultString(ret) );
          goto error;
     }

     dfb_surface_unlock_buffer( data->decode_surface, &lock );

     dfb_state_init( &state, data->base.core );

     state.modified |= SMF_CLIP;

     state.clip =  DFB_REGION_INIT_FROM_RECTANGLE_VALS( rect.x, rect.y, rect.w, rect.h );
     src_rect = (DFBRectangle){0, 0, data->width, data->height};

     dfb_state_set_source( &state, data->decode_surface );
     dfb_state_set_destination( &state, dst_surface );

     dfb_gfxcard_batchstretchblit( &src_rect, &rect, 1, &state );

     data->serial = &state.serial;

     dfb_state_set_source(&state, NULL);
     dfb_state_set_destination(&state, NULL);

     dfb_state_destroy(&state);

     if (data->base.render_callback) {
          DFBRectangle r = { 0, 0, data->width, data->height };
          cb_result=data->base.render_callback( &r, data->base.render_callback_context );
     }

     if (cb_result == DIRCR_OK) {
          data->base.buffer->Release( data->base.buffer );
          data->base.buffer = NULL;
     }

     return DFB_OK;

error:
     if (data->decode_surface && lock.pitch)
          dfb_surface_unlock_buffer( data->decode_surface, &lock );

     dfb_surface_unref( data->decode_surface );

     data->base.buffer->Release( data->base.buffer );
     data->base.buffer = NULL;

     return ret;
}
Beispiel #11
0
int
main( int argc, char *argv[] )
{
     DirectResult         ret;
     FusionWorld         *world;
     FusionCall           call = {0};
     FusionSHMPoolShared *pool;
     void                *buffer;
     int           i, max_busy = 0, active = 1;
     long long     t1 = 0, t2;
     long long     start       = 0;
     long long     bytes       = 0;
     long long     last_bytes  = 0;
     unsigned long blocks      = 0;
     unsigned long last_blocks = 0;
     unsigned long last_busy   = 0;
     u32           checksum    = 0;
     bool          produce     = true;
     int           delay       = 66000;

     if (parse_cmdline( argc, argv ))
          return -1;

     if (bit_rate) {
          int blocks_per_sec = (bit_rate * 1024 / 8) / block_size;

          if (blocks_per_sec < 100)
               delay = 900000 / blocks_per_sec - 2000;
          else
               delay = 300000 * 100 / blocks_per_sec;

          num_blocks = bit_rate * 1024 / 8 / block_size * delay / 900000;

          if (num_blocks > MAX_NUM_BLOCKS)
               num_blocks = MAX_NUM_BLOCKS;

          if (!num_blocks) {
               num_blocks = 1;
               delay = 970 * block_size / (bit_rate * 1024 / 8) * 1000 - 2000;
          }
     }

     sync();

     if (run_busy) {
          pthread_create( &busy_thread, NULL, busy_loop, NULL );

          printf( "Calibrating...\n" );
     
          pthread_mutex_lock( &busy_lock );
     
          for (i=0; i<7; i++) {
               int busy_rate;
     
               busy_count = 0;
     
               t1 = get_millis();
               pthread_mutex_unlock( &busy_lock );
     
               usleep( 300000 );
     
               pthread_mutex_lock( &busy_lock );
               t2 = get_millis();
     
               busy_rate = busy_count * 1000 / (t2 - t1);
     
               if (busy_rate > max_busy)
                    max_busy = busy_rate;
          }
     
          printf( "Calibrating done. (%d busy counts/sec)\n", max_busy );
     }

     ret = fusion_enter( -1, 23, FER_MASTER, &world );
     if (ret)
          return ret;

     ret = fusion_call_init( &call, call_handler, NULL, world );
     if (ret)
          return ret;

     ret = fusion_shm_pool_create( world, "Stream Buffer", block_size + 8192, false, &pool );
     if (ret)
          return ret;

     ret = fusion_shm_pool_allocate( pool, block_size, false, true, &buffer );
     if (ret)
          return ret;



     /*
      * Do the fork() magic!
      */
     if (do_fork) {
          fusion_world_set_fork_action( world, FFA_FORK );

          switch (fork()) {
               case -1:
                    D_PERROR( "fork() failed!\n" );
                    return -1;

               case 0:
                    /* child continues as the producer */
                    run_busy = false;
                    break;

               default:
                    /* parent is the consumer (callback in Fusion Dispatch thread) */
                    produce = false;

                    usleep( 50000 );
          }

          fusion_world_set_fork_action( world, FFA_CLOSE );
     }


     start = t1 = get_millis();

     if (run_busy) {
          busy_count = 0;
          pthread_mutex_unlock( &busy_lock );
     }

#ifdef LINUX_2_4
     delay -= 10000;
#endif

     do {
          if (bit_rate || !produce) {
               if (delay > 10)
                    usleep( delay );
          }

          if (produce) {
               for (i=0; i<num_blocks; i++) {
                    int  n;
                    u32  retsum;
                    u32 *values = buffer;

                    for (n=0; n<block_size/4; n++) {
                         values[n] = n;
                         checksum += n;
                    }

                    bytes += block_size;

                    fusion_call_execute( &call, do_thread ? FCEF_NODIRECT : FCEF_NONE,
                                         0, buffer, (int*) &retsum );

                    if (retsum != checksum)
                         D_ERROR( "Checksum returned by consumer (0x%08x) does not match 0x%08x!\n", retsum, checksum );
               }

               blocks += num_blocks;
          }


          t2 = get_millis();
          if (t2 - t1 > 2000) {
               if (produce) {
                    long long kbits = 0, avgkbits, total_time, diff_time, diff_bytes;

                    printf( "\n\n\n" );

                    total_time = t2 - start;
                    diff_time  = t2 - t1;
                    diff_bytes = bytes - last_bytes;

                    avgkbits   = (long long)bytes * 8LL * 1000LL / (long long)total_time / 1024LL;

                    if (diff_time)
                         kbits = (long long)diff_bytes * 8LL * 1000LL / (long long)diff_time / 1024LL;

                    printf( "Total Time:       %7lld ms\n", total_time );
                    printf( "Stream Size:      %7lld kb\n", bytes / 1024 );
                    printf( "Stream Rate:      %7lld kb/sec -> %lld.%03lld MBit (avg. %lld.%03lld MBit)\n",
                            kbits / 8,
                            (kbits * 1000 / 1024) / 1000, (kbits * 1000 / 1024) % 1000,
                            (avgkbits * 1000 / 1024) / 1000, (avgkbits * 1000 / 1024) % 1000 );
                    printf( "\n" );


                    if (last_bytes && bit_rate) {
                         long long diff_bytes = (bytes - last_bytes) * 1000 / (t2 - t1);
                         long long need_bytes = bit_rate * 1024 / 8;

                         if (diff_bytes) {
                              int new_blocks = (num_blocks * need_bytes + diff_bytes/2) / diff_bytes;

                              num_blocks = (new_blocks + num_blocks + 1) / 2;

                              if (num_blocks > MAX_NUM_BLOCKS)
                                   num_blocks = MAX_NUM_BLOCKS;
                         }
                    }


                    read_stat();

                    if (ftotal != ctotal && dtotal) {
                         int load, aload;

                         load  = 1000 - didle * 1000 / dtotal;
                         aload = 1000 - (cidle - fidle) * 1000 / (ctotal - ftotal);

                         printf( "Overall Stats\n" );
                         printf( "  Total Time:      %7lld ms\n", t2 - start );
                         printf( "  Block Size:      %7ld\n", block_size );
                         printf( "  Blocks/cycle:    %7ld\n", num_blocks );
                         printf( "  Blocks/second:   %7lld\n", (blocks - last_blocks) * 1000 / diff_time );
                         printf( "  Delay:           %7d\n", delay );
                         printf( "  CPU Load:        %5d.%d %% (avg. %d.%d %%)\n",
                                 load / 10, load % 10, aload / 10, aload % 10 );
                    }


                    last_bytes  = bytes;
                    last_blocks = blocks;
               }

               if (run_busy) {
                    pthread_mutex_lock( &busy_lock );

                    if (last_busy) {
                         int busy_diff;
                         int busy_rate, busy_load;
                         int abusy_rate, abusy_load;

                         busy_diff = busy_count - last_busy;
                         busy_rate = max_busy - (busy_diff * 1000 / (t2 - t1));
                         busy_load = busy_rate * 1000 / max_busy;
                         abusy_rate = max_busy - (busy_count * 1000 / (t2 - start));
                         abusy_load = abusy_rate * 1000 / max_busy;

                         printf( "  Real CPU Load:   %5d.%d %% (avg. %d.%d %%)\n",
                                 busy_load / 10, busy_load % 10,
                                 abusy_load / 10, abusy_load % 10 );
                    }

                    last_busy = busy_count;

                    pthread_mutex_unlock( &busy_lock );
               }

               t1 = t2;
          }
     } while (active > 0);


     if (run_busy) {
          busy_alive = 0;

          pthread_join( busy_thread, NULL );
     }

     return -1;
}
Beispiel #12
0
int main(int argc, char **argv) {
	int width = 640;
	int height = 480;
    int fd = open("/dev/video0", O_RDWR | O_NONBLOCK);
    int stat = 0;

    if (fd < 0) {
        D_ERROR("can not open device.");
        return -1;
    }

    struct v4l2_capability cap = {0};
    stat = ioctl(fd, VIDIOC_QUERYCAP, &cap);

    if (stat == -1) {
        D_ERROR("can not get device capability.");
        return -1;
    }

    print_cap(&cap);

    int input_index = 0;
    stat = ioctl(fd, VIDIOC_G_INPUT, &input_index);

    if (stat == -1) {
        D_ERROR("can not get current input");
        return -1;
    }


    D_PVAR_INT(input_index);
    struct v4l2_input input;
    memset(&input, 0, sizeof(input));
    input.index = 0;

    D_PRINT("enum input");

    do {
        stat = ioctl(fd, VIDIOC_ENUMINPUT, &input);

        if (stat == -1) {
            break;
        }

        D_PVAR_INT(input.index);
        D_PVAR_STR(input.name);
        input.index++;
    } while (1);

    D_PRINT("enum input end");


    v4l2_std_id std;
    do {
        stat = ioctl(fd, VIDIOC_QUERYSTD, &std);
    } while (stat == -1 && errno == EAGAIN);
    if (stat == -1) {
        D_ERROR("can not get current video standard.");
        //return -1;
    }

    struct v4l2_standard standard;
    memset(&standard, 0, sizeof(standard));

    D_PRINT("enum video standard.");
    while (1) {
        stat = ioctl(fd, VIDIOC_ENUMSTD, &standard);

        if (stat == -1) {
            break;
        }

        D_PVAR_INT(standard.index);
        D_PVAR_STR(standard.name);
        if (std == standard.id) {
            D_PRINT("above is current video standard.");
        }

        standard.index++;
    }
    D_PRINT("enum video standard end.");



    struct v4l2_fmtdesc fmtdesc;
    memset(&fmtdesc, 0, sizeof(fmtdesc));
    fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    D_PRINT("enum image format.");
    while (1) {
        stat = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc);

        if (stat == -1) {
            break;
        }

        D_PVAR_INT(fmtdesc.index);
        D_PVAR_STR(fmtdesc.description);
        fmtdesc.index++;
    }
    D_PRINT("enum image format end.");


    struct v4l2_format fmt;
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = width;
    fmt.fmt.pix.height = height;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

    D_PRINT("set format");

    stat = ioctl(fd, VIDIOC_S_FMT, &fmt);

    if (stat == -1) {
    	D_ERROR("can not set video format");
    	return -1;
    }

    if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
    	D_ERROR("can not set specific format");
    	struct v4l2_fmtdesc fmtqury;
    	memset(&fmtqury, 0, sizeof(fmtqury));

    	fmtqury.pixelformat == fmt.fmt.pix.pixelformat;
    	stat = ioctl(fd, VIDIOC_ENUM_FMT, &fmtqury);

    	if (stat == -1) {
    		printf("real format: %s\n", fmtqury.description);
    	}
    	printf("format = %d\n", fmt.fmt.pix.pixelformat);
    	return -1;
    }

    struct v4l2_requestbuffers req;

    memset(&req, 0, sizeof(struct v4l2_requestbuffers));

    req.count = 4;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;

    stat = ioctl(fd, VIDIOC_REQBUFS, &req);

    if (stat == -1) {
    	D_ERROR("can not require buffers");
    	return -1;
    }

    buffers = (struct buffer *)malloc(sizeof(struct buffer) * req.count);

    int i = 0;
    for (i = 0; i < req.count; i++) {
    	struct v4l2_buffer buf;
    	memset(&buf, 0, sizeof(buf));

    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	buf.index = i;

    	stat = ioctl(fd, VIDIOC_QUERYBUF, &buf);

    	if (stat == -1) {
    		D_ERROR("can not query buffer");
    		return -1;
    	}

    	buffers[i].length = buf.length;
    	buffers[i].start = mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);

    	if (MAP_FAILED == buffers[i].start) {
    		D_ERROR("mmap error");
    		return -1;
    	}

    	stat = ioctl(fd, VIDIOC_QBUF, &buf);

    	if (stat == -1) {
    		D_ERROR("can not put buf in queue");
    		return -1;
    	}
    }




    enum v4l2_buf_type stream_type =  V4L2_BUF_TYPE_VIDEO_CAPTURE;

    D_PRINT("stream on.");
    stat = ioctl(fd, VIDIOC_STREAMON, &stream_type);

    if (stat == -1) {
    	D_ERROR("can not turn stream on");
    	return -1;
    }

    i = 0;
    char filename[4096] = {0};

    D_PRINT("start loop");

    while (1) {
    	fd_set fds;
    	FD_ZERO(&fds);
    	FD_SET(fd, &fds);
    	int ret = 0;
    	ret = select(fd + 1, &fds, NULL, NULL, NULL);

    	if (ret == -1) {
    		if (EINTR == errno) {
    			continue;
    		}

    		D_ERROR("select error.");
    		return -1;
    	}

    	struct v4l2_buffer buf;
    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	stat = ioctl(fd, VIDIOC_DQBUF, &buf);

    	if (stat == -1) {
    		D_ERROR("can not out queue");
    		return -1;
    	}


    	sprintf(filename, "out/frame%d.jpg", i);

    	printf("index: %d, out: %s\n", buf.index, filename);
    	FILE *out = fopen(filename, "wb");

    	//fprintf(out, "P6\n%d %d\n255\n",640, 480);

    	fwrite(buffers[buf.index].start, 1, buf.length, out);
    	fclose(out);

    	ioctl(fd, VIDIOC_QBUF, &buf);
    	i++;
    }


    stat = ioctl(fd, VIDIOC_STREAMOFF, &stream_type);

        if (stat == -1) {
        	D_ERROR("can not turn stream off");
        	return -1;
        }
    close(fd);
    return 0;
}
static DFBResult
sdlAllocateBuffer( CoreSurfacePool       *pool,
                   void                  *pool_data,
                   void                  *pool_local,
                   CoreSurfaceBuffer     *buffer,
                   CoreSurfaceAllocation *allocation,
                   void                  *alloc_data )
{
     DFBResult          ret;
     CoreSurface       *surface;
     SDLAllocationData *alloc = alloc_data;

     D_DEBUG_AT( SDL_Pool, "%s()\n", __FUNCTION__ );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     surface = buffer->surface;
     D_MAGIC_ASSERT( surface, CoreSurface );

     if (surface->type & CSTF_LAYER) {
          dfb_sdl->screen = NULL; /* clear? */

          ret = dfb_sdl_set_video_mode( dfb_sdl_core, &surface->config );
          if (ret) {
               D_DERROR( ret, "SDL/Surface: dfb_sdl_set_video_mode() failed!\n" );
               return ret;
          }

          D_ASSERT( dfb_sdl->screen != NULL );

          if (!dfb_sdl->screen) {
               D_ERROR( "SDL/Surface: No screen surface!?\n" );
               return DFB_BUG;
          }

          alloc->sdl_surf = dfb_sdl->screen;

          D_DEBUG_AT( SDL_Pool, "  -> screen surface  %dx%d, %d, 0x%08x, pitch %d\n",
                      dfb_sdl->screen->w, dfb_sdl->screen->h, dfb_sdl->screen->format->BitsPerPixel,
                      dfb_sdl->screen->flags, dfb_sdl->screen->pitch );

          allocation->flags |= CSALF_ONEFORALL;
     }
     else {
          DFBSurfacePixelFormat  format = surface->config.format;
          Uint32                 flags  = SDL_HWSURFACE;// | SDL_ASYNCBLIT | SDL_FULLSCREEN;
          Uint32                 rmask;
          Uint32                 gmask;
          Uint32                 bmask;
          Uint32                 amask;

          if (surface->config.caps & DSCAPS_FLIPPING)
               flags |= SDL_DOUBLEBUF;

          switch (format) {
               case DSPF_A8:
                    rmask = 0x00;
                    gmask = 0x00;
                    bmask = 0x00;
                    amask = 0xff;
                    break;

               case DSPF_RGB16:
                    rmask = 0xf800;
                    gmask = 0x07e0;
                    bmask = 0x001f;
                    amask = 0x0000;
                    break;

               case DSPF_RGB32:
                    rmask = 0x00ff0000;
                    gmask = 0x0000ff00;
                    bmask = 0x000000ff;
                    amask = 0x00000000;
                    break;

               case DSPF_ARGB:
                    rmask = 0x00ff0000;
                    gmask = 0x0000ff00;
                    bmask = 0x000000ff;
                    amask = 0xff000000;
                    break;

               default:
                    D_ERROR( "SDL/Surface: %s() has no support for %s!\n",
                             __FUNCTION__, dfb_pixelformat_name(format) );
                    return DFB_UNSUPPORTED;
          }

          D_DEBUG_AT( SDL_Pool, "  -> SDL_CreateRGBSurface( 0x%08x, "
                      "%dx%d, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x )\n",
                      flags, surface->config.size.w, surface->config.size.h,
                      DFB_BITS_PER_PIXEL(format), rmask, gmask, bmask, amask );

          alloc->sdl_surf = SDL_CreateRGBSurface( flags,
                                                  surface->config.size.w,
                                                  surface->config.size.h,
                                                  DFB_BITS_PER_PIXEL(format),
                                                  rmask, gmask, bmask, amask );
          if (!alloc->sdl_surf) {
               D_ERROR( "SDL/Surface: SDL_CreateRGBSurface( 0x%08x, "
                        "%dx%d, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x ) failed!\n",
                        flags, surface->config.size.w, surface->config.size.h,
                        DFB_BITS_PER_PIXEL(format), rmask, gmask, bmask, amask );

               return DFB_FAILURE;
          }
     }

     D_MAGIC_SET( alloc, SDLAllocationData );

     return DFB_OK;
}
Beispiel #14
0
static DirectResult
send_discover_and_receive_info( VoodooLink        *link,
                                VoodooPlayVersion *ret_version,
                                VoodooPlayInfo    *ret_info )
{
     struct {
          VoodooMessageHeader header;
          VoodooPlayVersion   version;
          VoodooPlayInfo      info;
     } msg;

     int                 ret;
     VoodooMessageHeader header;
     size_t              got;

     D_INFO( "Voodoo/Player: Sending VMSG_DISCOVER message via Voodoo TCP port...\n" );

     header.size   = sizeof(VoodooMessageHeader);
     header.serial = 0;
     header.type   = VMSG_DISCOVER;

     ret = link->Write( link, &header, sizeof(header) );
     if (ret < 0) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Player: Failed to send VMSG_DISCOVER message via Voodoo TCP port!\n" );
          return ret;
     }


     // wait for up to one second (old server will not reply anything, so we have to timeout)
     ret = link->WaitForData( link, 1000 );
     if (ret) {
          D_DERROR( ret, "Voodoo/Player: Failed to wait for reply after sending VMSG_DISCOVER message via Voodoo TCP port!\n" );
          return ret;
     }

     D_INFO( "Voodoo/Player: New Voodoo Server with VMSG_DISCOVER support, reading version/info (SENDINFO) reply...\n" );


     got = 0;

     while (got < sizeof(msg)) {
          ret = link->Read( link, (u8*) &msg + got, sizeof(msg) - got );
          if (ret < 0) {
               ret = errno2result( errno );
               D_PERROR( "Voodoo/Player: Failed to read after sending VMSG_DISCOVER message via Voodoo TCP port!\n" );
               return ret;
          }

          got += ret;
     }


     if (msg.header.type != VMSG_SENDINFO) {
          D_ERROR( "Voodoo/Player: Received message after sending VMSG_DISCOVER message via Voodoo TCP port is no VMSG_SENDINFO!\n");
          return DR_INVARG;
     }

     *ret_version = msg.version;
     *ret_info    = msg.info;

     D_INFO( "Voodoo/Player: Voodoo Server sent name '%s', version %d.%d.%d\n",
             msg.info.name, msg.version.v[1], msg.version.v[2], msg.version.v[3] );

     return DR_OK;
}
Beispiel #15
0
static int
ik_btr_kv_operate(enum ik_btr_opc opc, char *str, bool verbose)
{
	int		count = 0;
	umem_id_t	rec_mmid;
	int		rc;

	if (daos_handle_is_inval(ik_toh)) {
		D_ERROR("Can't find opened tree\n");
		return -1;
	}

	while (str != NULL && !isspace(*str) && *str != '\0') {
		char	   *val = NULL;
		daos_iov_t  key_iov;
		daos_iov_t  val_iov;
		uint64_t    key;

		key = strtoul(str, NULL, 0);

		if (opc == BTR_OPC_UPDATE) {
			val = strchr(str, IK_SEP_VAL);
			if (val == NULL) {
				D_ERROR("Invalid parameters %s(errno %d)\n",
					str, errno);
				return -1;
			}
			str = ++val;
		}

		str = strchr(str, IK_SEP);
		if (str != NULL) {
			*str = '\0';
			str++;
		}

		daos_iov_set(&key_iov, &key, sizeof(key));
		switch (opc) {
		default:
			return -1;
		case BTR_OPC_UPDATE:
			daos_iov_set(&val_iov, val, strlen(val) + 1);
			rc = dbtree_update(ik_toh, &key_iov, &val_iov);
			if (rc != 0) {
				D_ERROR("Failed to update "DF_U64":%s\n",
					key, val);
				return -1;
			}
			break;

		case BTR_OPC_DELETE:
			rc = dbtree_delete(ik_toh, &key_iov, NULL);
			if (rc != 0) {
				D_ERROR("Failed to delete "DF_U64"\n", key);
				return -1;
			}
			if (verbose)
				D_PRINT("Deleted key "DF_U64"\n", key);

			if (dbtree_is_empty(ik_toh) && verbose)
				D_PRINT("Tree is empty now\n");
			break;

		case BTR_OPC_DELETE_RETAIN:
			rc = dbtree_delete(ik_toh, &key_iov, &rec_mmid);
			if (rc != 0) {
				D_ERROR("Failed to delete "DF_U64"\n", key);
				return -1;
			}

			/** Verify and delete rec_mmid here */
			rc = btr_rec_verify_delete(&rec_mmid, &key_iov);
			if (rc != 0) {
				D_ERROR("Failed to verify and delete rec\n");
				return -1;
			}

			if (verbose)
				D_PRINT("Deleted key "DF_U64"\n", key);
			if (dbtree_is_empty(ik_toh) && verbose)
				D_PRINT("Tree is empty now\n");
			break;

		case BTR_OPC_LOOKUP:
			D_DEBUG(DB_TEST, "Looking for "DF_U64"\n", key);

			daos_iov_set(&val_iov, NULL, 0); /* get address */
			rc = dbtree_lookup(ik_toh, &key_iov, &val_iov);
			if (rc != 0) {
				D_ERROR("Failed to lookup "DF_U64"\n", key);
				return -1;
			}

			if (verbose) {
				D_PRINT("Found key "DF_U64", value %s\n",
					key, (char *)val_iov.iov_buf);
			}
			break;
		}
		count++;
	}
	if (verbose)
		D_PRINT("%s %d record(s)\n", btr_opc2str(opc), count);
	return 0;
}
Beispiel #16
0
static int
crt_proc_daos_iod_t(crt_proc_t proc, daos_iod_t *dvi)
{
	crt_proc_op_t	proc_op;
	int		rc;
	int		i;
	uint32_t	existing_flags = 0;

	if (proc == NULL || dvi == NULL) {
		D_ERROR("Invalid parameter, proc: %p, data: %p.\n", proc, dvi);
		return -DER_INVAL;
	}

	rc = crt_proc_d_iov_t(proc, &dvi->iod_name);
	if (rc != 0)
		return rc;

	rc = crt_proc_daos_csum_buf_t(proc, &dvi->iod_kcsum);
	if (rc != 0)
		return rc;

	rc = crt_proc_memcpy(proc, &dvi->iod_type, sizeof(dvi->iod_type));
	if (rc != 0)
		return -DER_HG;

	rc = crt_proc_uint64_t(proc, &dvi->iod_size);
	if (rc != 0)
		return -DER_HG;

	rc = crt_proc_uint32_t(proc, &dvi->iod_nr);
	if (rc != 0)
		return -DER_HG;

	if (dvi->iod_nr == 0 && dvi->iod_type != DAOS_IOD_ARRAY) {
		D_ERROR("invalid I/O descriptor, iod_nr = 0\n");
		return -DER_HG;
	}

	rc = crt_proc_get_op(proc, &proc_op);
	if (rc != 0)
		return -DER_HG;

	if (proc_op == CRT_PROC_ENCODE) {
		if (dvi->iod_type == DAOS_IOD_ARRAY && dvi->iod_recxs != NULL)
			existing_flags |= IOD_REC_EXIST;
		if (dvi->iod_csums != NULL)
			existing_flags |= IOD_CSUM_EXIST;
		if (dvi->iod_eprs != NULL)
			existing_flags |= IOD_EPRS_EXIST;
	}

	rc = crt_proc_uint32_t(proc, &existing_flags);
	if (rc != 0)
		return -DER_HG;

	if (proc_op == CRT_PROC_DECODE) {
		if (existing_flags & IOD_REC_EXIST) {
			D_ALLOC_ARRAY(dvi->iod_recxs, dvi->iod_nr);
			if (dvi->iod_recxs == NULL)
				D_GOTO(free, rc = -DER_NOMEM);
		}

		if (existing_flags & IOD_CSUM_EXIST) {
			D_ALLOC_ARRAY(dvi->iod_csums, dvi->iod_nr);
			if (dvi->iod_csums == NULL)
				D_GOTO(free, rc = -DER_NOMEM);
		}

		if (existing_flags & IOD_EPRS_EXIST) {
			D_ALLOC_ARRAY(dvi->iod_eprs, dvi->iod_nr);
			if (dvi->iod_eprs == NULL)
				D_GOTO(free, rc = -DER_NOMEM);
		}
	}

	if (existing_flags & IOD_REC_EXIST) {
		for (i = 0; i < dvi->iod_nr; i++) {
			rc = crt_proc_daos_recx_t(proc, &dvi->iod_recxs[i]);
			if (rc != 0) {
				if (proc_op == CRT_PROC_DECODE)
					D_GOTO(free, rc);
				return rc;
			}
		}
	}

	if (existing_flags & IOD_CSUM_EXIST) {
		for (i = 0; i < dvi->iod_nr; i++) {
			rc = crt_proc_daos_csum_buf_t(proc, &dvi->iod_csums[i]);
			if (rc != 0) {
				if (proc_op == CRT_PROC_DECODE)
					D_GOTO(free, rc);
				return rc;
			}
		}
	}

	if (existing_flags & IOD_EPRS_EXIST) {
		for (i = 0; i < dvi->iod_nr; i++) {
			rc = crt_proc_daos_epoch_range_t(proc,
							 &dvi->iod_eprs[i]);
			if (rc != 0) {
				if (proc_op == CRT_PROC_DECODE)
					D_GOTO(free, rc);
				return rc;
			}
		}
	}

	if (proc_op == CRT_PROC_FREE) {
free:
		if (dvi->iod_recxs != NULL)
			D_FREE(dvi->iod_recxs);
		if (dvi->iod_csums != NULL)
			D_FREE(dvi->iod_csums);
		if (dvi->iod_eprs != NULL)
			D_FREE(dvi->iod_eprs);
	}

	return rc;
}
Beispiel #17
0
static int
ik_btr_iterate(char *args)
{
	daos_handle_t	ih;
	int		i;
	int		d;
	int		del;
	int		rc;
	int		opc;
	char		*err;

	if (daos_handle_is_inval(ik_toh)) {
		D_ERROR("Can't find opened tree\n");
		return -1;
	}

	rc = dbtree_iter_prepare(ik_toh, BTR_ITER_EMBEDDED, &ih);
	if (rc != 0) {
		err = "initialize";
		goto failed;
	}

	if (args[0] == 'b')
		opc = BTR_PROBE_LAST;
	else
		opc = BTR_PROBE_FIRST;

	if (strlen(args) >= 3 && args[1] == ':')
		del = atoi(&args[2]);
	else
		del = 0;

	for (i = d = 0;; i++) {
		daos_iov_t	key_iov;
		daos_iov_t	val_iov;
		uint64_t	key;

		if (i == 0 || (del != 0 && d <= del)) {
			rc = dbtree_iter_probe(ih, opc, DAOS_INTENT_DEFAULT,
					       NULL, NULL);
			if (rc == -DER_NONEXIST)
				break;

			if (rc != 0) {
				err = "probe";
				goto failed;
			}

			if (del != 0) {
				if (d == del)
					del = d = 0; /* done */
				else
					d++;
			}
		}

		daos_iov_set(&key_iov, NULL, 0);
		daos_iov_set(&val_iov, NULL, 0);
		rc = dbtree_iter_fetch(ih, &key_iov, &val_iov, NULL);
		if (rc != 0) {
			err = "fetch";
			goto failed;
		}

		D_ASSERT(key_iov.iov_len == sizeof(key));
		memcpy(&key, key_iov.iov_buf, sizeof(key));

		if (d != 0) { /* delete */
			D_PRINT("Delete "DF_U64": %s\n",
				key, (char *)val_iov.iov_buf);
			rc = dbtree_iter_delete(ih, NULL);
			if (rc != 0) {
				err = "delete";
				goto failed;
			}

		} else { /* iterate */
			D_PRINT(DF_U64": %s\n", key, (char *)val_iov.iov_buf);

			if (opc == BTR_PROBE_LAST)
				rc = dbtree_iter_prev(ih);
			else
				rc = dbtree_iter_next(ih);

			if (rc == -DER_NONEXIST)
				break;

			if (rc != 0) {
				err = "move";
				goto failed;
			}
		}
	}

	D_PRINT("%s iterator: total %d, deleted %d\n",
		opc == BTR_PROBE_FIRST ? "forward" : "backward", i, d);
	dbtree_iter_finish(ih);
	return 0;
 failed:
	D_PRINT("Iterator %s failed: %d\n", err, rc);
	dbtree_iter_finish(ih);
	return -1;
}
Beispiel #18
0
void *
direct_dbg_realloc( const char *file, int line, const char *func, const char *what, void *mem, size_t bytes )
{
     unsigned long *val;
     MemDesc       *desc;

     D_DEBUG_AT( Direct_Mem, "  *"_ZUn(6)" bytes [%s:%d in %s()] '%s' <- %p\n", bytes, file, line, func, what, mem );

     if (!mem)
          return direct_dbg_malloc( file, line, func, bytes );

     if (!bytes) {
          direct_dbg_free( file, line, func, what, mem );
          return NULL;
     }

     val = (unsigned long*)((char*) mem - DISABLED_OFFSET);

     if (val[0] == ~0) {
          D_DEBUG_AT( Direct_Mem, "  *"_ZUn(6)" bytes [%s:%d in %s()] '%s'\n", bytes, file, line, func, what );

          val = direct_realloc( val, bytes + DISABLED_OFFSET );

          D_DEBUG_AT( Direct_Mem, "  '-> %p\n", val );

          if (val) {
               D_ASSERT( val[0] == ~0 );

               mem = val;

               return (char*) mem + DISABLED_OFFSET;
          }

          return NULL;
     }

     /* Debug only. */
     direct_mutex_lock( &alloc_lock );

     desc = (MemDesc*)((char*) mem - sizeof(MemDesc));
     D_ASSERT( desc->mem == mem );

     if (direct_hash_remove( &alloc_hash, (unsigned long) mem )) {
          D_ERROR( "Direct/Mem: Not reallocating unknown %p (%s) from [%s:%d in %s()] - corrupt/incomplete list?\n",
                   mem, what, file, line, func );

          mem = direct_dbg_malloc( file, line, func, bytes );
     }
     else {
          void *new_mem = direct_realloc( desc, bytes + sizeof(MemDesc) );

          D_DEBUG_AT( Direct_Mem, "  '-> %p\n", new_mem );

          D_DEBUG_AT( Direct_Mem, "  %c"_ZUn(6)" bytes [%s:%d in %s()] (%s"_ZU") <- %p -> %p '%s'\n",
                      (bytes > desc->bytes) ? '>' : '<', bytes, file, line, func,
                      (bytes > desc->bytes) ? "+" : "", bytes - desc->bytes, mem, new_mem, what);

          if (desc->trace) {
               direct_trace_free_buffer( desc->trace );
               desc->trace = NULL;
          }

          if (!new_mem)
               D_WARN( "could not reallocate memory (%p: "_ZU"->"_ZU")", mem, desc->bytes, bytes );
          else
               desc = fill_mem_desc( new_mem, bytes, func, file, line, direct_trace_copy_buffer(NULL) );


          mem = desc->mem;
     }

     direct_mutex_unlock( &alloc_lock );

     return mem;
}
Beispiel #19
0
static DirectResult
init_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared,
           const char          *name,
           unsigned int         max_size,
           bool                 debug )
{
     DirectResult         ret;
     int                  fd;
     int                  size;
     FusionWorld         *world;
     FusionSHMPoolNew     pool_new    = { .pool_id = 0 };
     FusionSHMPoolAttach  pool_attach = { .pool_id = 0 };
     FusionEntryInfo      info;
     char                 buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n",
                 __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
     D_ASSERT( name != NULL );
     D_ASSERT( max_size > sizeof(shmalloc_heap) );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     D_ASSERT( pool != NULL );
     D_ASSERT( shared != NULL );

     /* Fill out information for new pool. */
     pool_new.max_size = max_size;

     pool_new.max_size += BLOCKALIGN(sizeof(shmalloc_heap)) +
                          BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) );

     /* Create the new pool. */
     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_NEW, &pool_new )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_NEW failed!\n" );
          return DR_FUSION;
     }

     /* Set the pool info. */
     info.type = FT_SHMPOOL;
     info.id   = pool_new.pool_id;

     snprintf( info.name, sizeof(info.name), "%s", name );

     ioctl( world->fusion_fd, FUSION_ENTRY_SET_INFO, &info );


     /* Set pool to attach to. */
     pool_attach.pool_id = pool_new.pool_id;

     /* Attach to the pool. */
     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" );

          while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
               if (errno != EINTR) {
                    D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
                    break;
               }
          }

          return DR_FUSION;
     }


     /* Generate filename. */
     snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
               fusion_world_index( shm->world ), pool_new.pool_id );

     /* Initialize the heap. */
     ret = __shmalloc_init_heap( shm, buf, pool_new.addr_base, max_size, &fd, &size );
     if (ret) {
          while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
               if (errno != EINTR) {
                    D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
                    break;
               }
          }

          return ret;
     }


     /* Initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = pool_new.pool_id;
     pool->fd       = fd;
     pool->filename = D_STRDUP( buf );

     /* Initialize shared data. */
     shared->active     = true;
     shared->debug      = debug;
     shared->shm        = shm->shared;
     shared->max_size   = pool_new.max_size;
     shared->pool_id    = pool_new.pool_id;
     shared->addr_base  = pool_new.addr_base;
     shared->heap       = pool_new.addr_base;
     shared->heap->pool = shared;

     fusion_skirmish_init( &shared->lock, name, world );


     D_MAGIC_SET( pool, FusionSHMPool );
     D_MAGIC_SET( shared, FusionSHMPoolShared );


     shared->name = SHSTRDUP( shared, name );

     return DR_OK;
}

static DirectResult
join_pool( FusionSHM           *shm,
           FusionSHMPool       *pool,
           FusionSHMPoolShared *shared )
{
     DirectResult         ret;
     int                  fd;
     FusionWorld         *world;
     FusionSHMPoolAttach  pool_attach = { .pool_id = 0 };
     char                 buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32];

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( shm->shared, FusionSHMShared );
     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );

#if !DIRECT_BUILD_DEBUGS
     if (shared->debug) {
          D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" );
          return DR_UNSUPPORTED;
     }
#endif

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );


     /* Set pool to attach to. */
     pool_attach.pool_id = shared->pool_id;

     /* Attach to the pool. */
     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) {
          if (errno == EINTR)
               continue;

          D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" );
          return DR_FUSION;
     }


     /* Generate filename. */
     snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs,
               fusion_world_index( shm->world ), shared->pool_id );

     /* Join the heap. */
     ret = __shmalloc_join_heap( shm, buf, pool_attach.addr_base, shared->max_size, &fd );
     if (ret) {
          while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) {
               if (errno != EINTR) {
                    D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" );
                    break;
               }
          }

          return ret;
     }


     /* Initialize local data. */
     pool->attached = true;
     pool->shm      = shm;
     pool->shared   = shared;
     pool->pool_id  = shared->pool_id;
     pool->fd       = fd;
     pool->filename = D_STRDUP( buf );


     D_MAGIC_SET( pool, FusionSHMPool );

     return DR_OK;
}

static void
leave_pool( FusionSHM           *shm,
            FusionSHMPool       *pool,
            FusionSHMPoolShared *shared )
{
     FusionWorld *world;

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( pool, FusionSHMPool );
     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" );
               break;
          }
     }

     if (munmap( shared->addr_base, shared->max_size ))
          D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );

     if (pool->fd != -1 && close( pool->fd ))
          D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );

     pool->attached = false;

     D_FREE( pool->filename );

     D_MAGIC_CLEAR( pool );
}

static void
shutdown_pool( FusionSHM           *shm,
               FusionSHMPool       *pool,
               FusionSHMPoolShared *shared )
{
     FusionWorld *world;

     D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared );

     D_MAGIC_ASSERT( shm, FusionSHM );
     D_MAGIC_ASSERT( pool, FusionSHMPool );
     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );

     world = shm->world;

     D_MAGIC_ASSERT( world, FusionWorld );

     SHFREE( shared, shared->name );

     fusion_dbg_print_memleaks( shared );

     while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" );
               break;
          }
     }

     if (munmap( shared->addr_base, shared->max_size ))
          D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename );

     if (pool->fd != -1 && close( pool->fd ))
          D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename );

     if (unlink( pool->filename ))
          D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename );

     shared->active = false;

     pool->attached = false;

     D_FREE( pool->filename );

     D_MAGIC_CLEAR( pool );

     fusion_skirmish_destroy( &shared->lock );

     D_MAGIC_CLEAR( shared );
}
Beispiel #20
0
/* HACK: implementation dumped in here for now, will move into context */
static DFBResult
wm_update_cursor( CoreWindowStack       *stack,
                  void                  *wm_data,
                  void                  *stack_data,
                  CoreCursorUpdateFlags  flags )
{
     DFBResult         ret;
     DFBRegion         old_region;
     WMData           *wmdata   = wm_data;
     StackData        *data     = stack_data;
     bool              restored = false;
     CoreLayer        *layer;
     CoreLayerRegion  *region;
     CardState        *state;
     CoreSurface      *surface;
     UniqueContext    *context;

     D_ASSERT( stack != NULL );
     D_ASSERT( stack->context != NULL );
     D_ASSERT( wm_data != NULL );
     D_ASSERT( stack_data != NULL );

     D_MAGIC_ASSERT( data, StackData );

     context = data->context;

     D_MAGIC_ASSERT( context, UniqueContext );

     /* Optimize case of invisible cursor moving. */
     if (!(flags & ~(CCUF_POSITION | CCUF_SHAPE)) && (!stack->cursor.opacity || !stack->cursor.enabled)) {
          context->cursor_bs_valid = false;
          return DFB_OK;
     }

     layer   = dfb_layer_at( context->layer_id );
     state   = &layer->state;
     region  = context->region;
     surface = context->surface;

     D_ASSERT( region != NULL );
     D_ASSERT( surface != NULL );

     if (flags & CCUF_ENABLE) {
          CoreSurface            *cursor_bs;
          DFBSurfaceCapabilities  caps = DSCAPS_NONE;

          dfb_surface_caps_apply_policy( stack->cursor.policy, &caps );

          D_ASSERT( context->cursor_bs == NULL );

          /* Create the cursor backing store surface. */
          ret = dfb_surface_create_simple( wmdata->core, stack->cursor.size.w, stack->cursor.size.h,
                                           region->config.format, caps, CSTF_SHARED | CSTF_CURSOR,
                                           0, /* FIXME: no shared cursor objects, no cursor id */
                                           NULL, &cursor_bs );
          if (ret) {
               D_ERROR( "WM/Default: Failed creating backing store for cursor!\n" );
               return ret;
          }

          ret = dfb_surface_globalize( cursor_bs );
          D_ASSERT( ret == DFB_OK );

          /* Ensure valid back buffer for now.
           * FIXME: Keep a flag to know when back/front have been swapped and need a sync.
           */
          switch (region->config.buffermode) {
               case DLBM_BACKVIDEO:
               case DLBM_TRIPLE:
                    dfb_gfx_copy( surface, surface, NULL );
                    break;

               default:
                    break;
          }

          context->cursor_bs = cursor_bs;
     }
     else {
          D_ASSERT( context->cursor_bs != NULL );

          /* restore region under cursor */
          if (context->cursor_drawn) {
               DFBRectangle rect = { 0, 0,
                                     context->cursor_region.x2 - context->cursor_region.x1 + 1,
                                     context->cursor_region.y2 - context->cursor_region.y1 + 1 };

               D_ASSERT( stack->cursor.opacity || (flags & CCUF_OPACITY) );
               D_ASSERT( context->cursor_bs_valid );

               dfb_gfx_copy_to( context->cursor_bs, surface, &rect,
                                context->cursor_region.x1, context->cursor_region.y1, false );

               context->cursor_drawn = false;

               old_region = context->cursor_region;
               restored   = true;
          }

          if (flags & CCUF_SIZE) {
               ret = dfb_surface_reformat( context->cursor_bs,
                                           stack->cursor.size.w, stack->cursor.size.h,
                                           context->cursor_bs->config.format );
               if (ret) {
                    D_ERROR( "WM/Default: Failed resizing backing store for cursor!\n" );
                    return ret;
               }
          }
     }

     if (flags & (CCUF_ENABLE | CCUF_POSITION | CCUF_SIZE | CCUF_OPACITY)) {
          context->cursor_bs_valid  = false;

          context->cursor_region.x1 = stack->cursor.x - stack->cursor.hot.x;
          context->cursor_region.y1 = stack->cursor.y - stack->cursor.hot.y;
          context->cursor_region.x2 = context->cursor_region.x1 + stack->cursor.size.w - 1;
          context->cursor_region.y2 = context->cursor_region.y1 + stack->cursor.size.h - 1;

          if (!dfb_region_intersect( &context->cursor_region, 0, 0, stack->width - 1, stack->height - 1 )) {
               D_BUG( "invalid cursor region" );
               return DFB_BUG;
          }
     }

     D_ASSERT( context->cursor_bs != NULL );

     if (flags & CCUF_DISABLE) {
          dfb_surface_unlink( &context->cursor_bs );
     }
     else if (stack->cursor.opacity) {
          /* backup region under cursor */
          if (!context->cursor_bs_valid) {
               DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &context->cursor_region );

               D_ASSERT( !context->cursor_drawn );

               /* FIXME: this requires using blitted flipping all the time,
                  but fixing it seems impossible, for now DSFLIP_BLIT is forced
                  in repaint_stack() when the cursor is enabled. */
               dfb_gfx_copy_to( surface, context->cursor_bs, &rect, 0, 0, true );

               context->cursor_bs_valid = true;
          }

          /* Set destination. */
          state->destination  = surface;
          state->modified    |= SMF_DESTINATION;

          /* Set clipping region. */
          dfb_state_set_clip( state, &context->cursor_region );

          /* draw cursor */
          unique_draw_cursor( stack, context, state, &context->cursor_region );

          /* Reset destination. */
          state->destination  = NULL;
          state->modified    |= SMF_DESTINATION;

          context->cursor_drawn = true;

          if (restored) {
               if (dfb_region_region_intersects( &old_region, &context->cursor_region ))
                    dfb_region_region_union( &old_region, &context->cursor_region );
               else
                    dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );

               dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );
          }
          else
               dfb_layer_region_flip_update( region, &context->cursor_region, DSFLIP_BLIT );
     }
     else if (restored)
          dfb_layer_region_flip_update( region, &old_region, DSFLIP_BLIT );

     return DFB_OK;
}
static DFBResult
x11Read( CoreSurfacePool       *pool,
         void                  *pool_data,
         void                  *pool_local,
         CoreSurfaceAllocation *allocation,
         void                  *alloc_data,
         void                  *destination,
         int                    pitch,
         const DFBRectangle    *rect )
{
     XImage            *image;
     XImage            *sub;
     x11PoolLocalData  *local = pool_local;
     x11AllocationData *alloc = alloc_data;
     DFBX11            *x11   = local->x11;

     D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
     D_DEBUG_AT( X11_Surfaces, "  -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
     D_ASSERT( destination != NULL );
     D_ASSERT( pitch >= 0 );
     DFB_RECTANGLE_ASSERT( rect );

     D_DEBUG_AT( X11_Surfaces, "  => %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );


     XLockDisplay( x11->display );

#if 1
     image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, destination, rect->w, rect->h, 32, pitch );
     if (!image) {
          D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth );
          XUnlockDisplay( x11->display );
          return DFB_FAILURE;
     }

     sub = XGetSubImage( x11->display, alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap, image, 0, 0 );
#else
     image = XGetImage( x11->display, alloc->window ? alloc->window : alloc->xid,
                        rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap );
#endif

     if (image) {
//          dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Read", false, image->data, image->bytes_per_line );

          /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */
          image->data = NULL;
          XDestroyImage( image );
     }

     XUnlockDisplay( x11->display );

#if 1
     if (!sub) {
          D_ERROR( "X11/Surfaces: XGetSubImage( %d,%d-%dx%d ) failed!\n", DFB_RECTANGLE_VALS(rect) );
          return DFB_FAILURE;
     }
#endif
     return DFB_OK;
}
Beispiel #22
0
int
main( int argc, char *argv[] )
{
     DirectResult ret;
     pid_t        child_pid;
     TestMessage  message = {0};

     DirectFBInit( &argc, &argv );

     ret = fusion_enter( -1, 0, FER_MASTER, &m_world );
     if (ret) {
          D_DERROR( ret, "fusion_enter() failed" );
          return ret;
     }

     MSG( "Entered world %d as master (FusionID %lu, pid %d)\n",
          fusion_world_index( m_world ), fusion_id( m_world ), getpid() );


     ret = fusion_ref_init( &m_ref, "Test", m_world );
     if (ret) {
          D_DERROR( ret, "fusion_ref_init() failed" );
          return -1;
     }


     MSG( "Adding local reference...\n" );

     fusion_ref_up( &m_ref, false );


     m_reactor = fusion_reactor_new( sizeof(TestMessage), "Test", m_world );
     if (!m_reactor) {
          D_ERROR( "fusion_reactor_new() failed\n" );
          return -1;
     }


     MSG( "Attaching to reactor...\n" );

     ret = fusion_reactor_attach( m_reactor, reaction_callback, NULL, &m_reaction );
     if (ret) {
          D_DERROR( ret, "fusion_reactor_attach() failed" );
          return ret;
     }


     MSG( ".........FORKING NOW.........\n" );

     fusion_world_set_fork_action( m_world, FFA_FORK );
     child_pid = fork();
     fusion_world_set_fork_action( m_world, FFA_CLOSE );

     switch (child_pid) {
          case -1:
               D_PERROR( "fork() failed" );
               break;

          case 0:
               setsid();
               MSG( "...arrived after fork() in child (pid %d)..\n", getpid() );
               MSG( "..child (FusionID %lu).\n", fusion_id( m_world ) );
               break;

          default:
               usleep( 200000 );
               MSG( "...returned from fork() in parent, child pid %d.\n", child_pid );
               break;
     }


     MSG( "Sending message via reactor...\n" );

     fusion_reactor_dispatch( m_reactor, &message, true, NULL );

     usleep( 200000 );


     MSG( "Removing local reference...\n" );

     fusion_ref_down( &m_ref, false );

     usleep( 200000 );


     MSG( "Exiting from world %d (FusionID %lu, pid %d)...\n",
          fusion_world_index( m_world ), fusion_id( m_world ), getpid() );

     fusion_exit( m_world, false );

     return 0;
}
Beispiel #23
0
// FIXME: refactor, optionally using lio_listio
static DirectResult
SendReceive( VoodooLink  *link,
             VoodooChunk *sends,
             size_t       num_send,
             VoodooChunk *recvs,
             size_t       num_recv )
{
     Link    *l = link->priv;
     size_t   i;
     ssize_t  ret;
     int      select_result;

     D_DEBUG_AT( Voodoo_Link, "%s( link %p, sends %p, num_send %zu, recvs %p, num_recv %zu )\n",
                 __func__, link, sends, num_send, recvs, num_recv );

     while (true) {
          fd_set fds_read;
          fd_set fds_write;
          struct timeval tv;

          FD_ZERO( &fds_read );
          FD_ZERO( &fds_write );

          if (num_recv)
               FD_SET( l->fd[0], &fds_read );

          if (num_send)
               FD_SET( l->fd[1], &fds_write );

          FD_SET( l->wakeup_fds[0], &fds_read );

          tv.tv_sec  = 0;
          tv.tv_usec = 1000000;

          D_DEBUG_AT( Voodoo_Link, "  -> select( %s%s )...\n", num_recv ? "R" : " ", num_send ? "W" : " " );
          select_result = select( MAX(MAX(l->wakeup_fds[0],l->fd[0]),l->fd[1])+1, &fds_read, &fds_write, NULL, &tv );
          switch (select_result) {
               default:
                    if (FD_ISSET( l->fd[1], &fds_write )) {
                         D_DEBUG_AT( Voodoo_Link, "  => WRITE\n" );

                         for (i=0; i<num_send; i++) {
                              while (sends[i].done != sends[i].length) {
#if 1
                                   ret = send( l->fd[1], sends[i].ptr, sends[i].length, MSG_DONTWAIT );
                                   if (ret < 0) {
                                        D_PERROR( "Voodoo/Link: Failed to send() data!\n" );
                                        return DR_IO;
                                   }
                                   else {
                                        sends[i].done += ret;
/*
                                        if (sends[i].done != sends[i].length)
                                             D_WARN( "partial send of %d/%d bytes", ret, sends[i].length );
                                        else
                                             D_WARN( "full send of %d bytes", ret, sends[i].length );
*/
                                        return DR_OK;
                                   }
#else
                                   struct aiocb cb;

                                   memset( &cb, 0, sizeof(struct aiocb) );

                                   cb.aio_fildes = l->fd[1];
                                   cb.aio_buf    = sends[i].ptr;
                                   cb.aio_nbytes = sends[i].length;
                                   cb.aio_offset = (intptr_t)-1;
                                   cb.aio_sigevent.sigev_notify = SIGEV_NONE;


                                   ret = aio_write( &cb );
                                   if (ret < 0) {
                                        D_PERROR( "Voodoo/Link: aio_write() failed!\n" );
                                        return DR_IO;
                                   }
                                   else {
                                        do {
                                             const struct aiocb *cbs[] = { &cb };

                                             ret = aio_suspend( cbs, 1, NULL );
                                             if (ret < 0) {
                                                  D_PERROR( "Voodoo/Link: aio_suspend() failed!\n" );
                                                  return DR_IO;
                                             }

                                             ret = aio_error( &cb );
                                        } while (ret == EINPROGRESS);

                                        switch (ret) {
                                             case 0:
                                                  ret = aio_return( &cb );
                                                  if (ret < 0) {
                                                       D_ERROR( "Voodoo/Link: aio_return() failed!\n     -> %s\n", strerror(ret) );
                                                       return DR_IO;
                                                  }
                                                  break;

                                             default:
                                                  D_ERROR( "Voodoo/Link: aio_error() failed!\n     -> %s\n", strerror(ret) );
                                                  return DR_IO;
                                        }

                                        sends[i].done += ret;
/*
                                        if (sends[i].done != sends[i].length)
                                             D_WARN( "partial send of %d/%d bytes", ret, sends[i].length );
                                        else
                                             D_WARN( "full send of %d bytes", ret, sends[i].length );
*/
                                        return DR_OK;
                                   }
#endif
                              }
                         }
                    }

                    if (FD_ISSET( l->fd[0], &fds_read )) {
                         D_DEBUG_AT( Voodoo_Link, "  => READ\n" );

                         for (i=0; i<num_recv; i++) {
                              ret = recv( l->fd[0], recvs[i].ptr, recvs[i].length, MSG_DONTWAIT );
                              if (ret < 0) {
                                   if (errno == EAGAIN) {
                                        break;
                                   }
                                   D_PERROR( "Voodoo/Link: Failed to recv() data!\n" );
                                   return DR_FAILURE;
                              }

                              if (!ret)
                                   return DR_IO;


                              recvs[i].done = ret;

                              if (recvs[i].done < recvs[i].length)
                                   break;
                         }
                    }

                    if (FD_ISSET( l->wakeup_fds[0], &fds_read )) {
                         D_DEBUG_AT( Voodoo_Link, "  => WAKE UP\n" );

                         static char buf[1000];
                         if (read( l->wakeup_fds[0], buf, sizeof(buf) ) < 0)
                              return errno2result( errno );

                         if (!FD_ISSET( l->fd[0], &fds_read ) && !FD_ISSET( l->fd[0], &fds_write ))
                              return DR_INTERRUPTED;
                    }

                    return DR_OK;

               case 0:
                    D_DEBUG_AT( Voodoo_Link, "  => TIMEOUT\n" );
                    return DR_TIMEOUT;

               case -1:
                    D_ERROR( "Voodoo/Link: select() failed!\n" );
                    return DR_FAILURE;
          }
     }

     return DR_OK;
}
Beispiel #24
0
static DirectResult
SendReceive( VoodooLink  *link,
             VoodooChunk *sends,
             size_t       num_send,
             VoodooChunk *recvs,
             size_t       num_recv )
{
     Link    *l = link->priv;
     size_t   i;
     ssize_t  ret;
     DWORD    wait_result;

//     direct_mutex_lock( &l->lock );

     for (i=0; i<num_send; i++) {
          //printf("writing %d\n",sends[i].length);
          ret = send( l->socket, sends[i].ptr, sends[i].length, 0 );
          //printf("wrote %d/%d\n",ret,sends[i].length);
          if (ret < 0) {
               if (WSAGetLastError() == 10035) {
                    break;
               }
               D_PERROR( "Voodoo/Link: Failed to send() data error %d!\n", WSAGetLastError() );
          }
          else {
               sends[i].done = (size_t) ret;

               if (sends[i].done != sends[i].length) {
                    D_UNIMPLEMENTED();
               //               direct_mutex_unlock( &l->lock );
                    return DR_UNIMPLEMENTED;
               }

               return DR_OK;
          }
     }


     while (true) {
          LONG events = 0;
          WSANETWORKEVENTS WsaNetworkEvents;

          if (num_recv) {
               //printf("wait for recv\n");
               events |= FD_READ;
          }

          if (num_send) {
               //printf("wait for send\n");
               events |= FD_WRITE;
          }

          WSAEventSelect( l->socket, l->event, events );

          wait_result = WSAWaitForMultipleEvents( 1, &l->event, FALSE, 10, FALSE );
          switch (wait_result) {
               case WSA_WAIT_EVENT_0:
                    WSAResetEvent( l->event );

                    WSAEnumNetworkEvents(l->socket, l->event, &WsaNetworkEvents);
                    //printf("<-- events 0x%08x\n",WsaNetworkEvents.lNetworkEvents);

                    if (!WsaNetworkEvents.lNetworkEvents)
                         return DR_INTERRUPTED;

                    if (WsaNetworkEvents.lNetworkEvents & FD_WRITE) {
                         //printf("<-- event write\n");

                         for (i=0; i<num_send; i++) {
                              //printf("writing %d\n",sends[i].length);
                              ret = send( l->socket, sends[i].ptr, sends[i].length, 0 );
                              //printf("wrote %d/%d\n",ret,sends[i].length);
                              if (ret < 0) {
                                   if (WSAGetLastError() == 10035) {
                                        break;
                                   }
                                   D_PERROR( "Voodoo/Link: Failed to send() data error %d!\n", WSAGetLastError() );
                                   return DR_IO;
                              }
                              else {
                                   sends[i].done = (size_t) ret;
                         
                                   if (sends[i].done != sends[i].length) {
                                        D_UNIMPLEMENTED();
                                   //               direct_mutex_unlock( &l->lock );
                                        return DR_UNIMPLEMENTED;
                                   }
                         
                                   return DR_OK;
                              }
                         }
                    }
     
                    if (WsaNetworkEvents.lNetworkEvents & FD_READ) {
                         //printf("<-- event read\n");

                         for (i=0; i<num_recv; i++) {
                              ret = recv( l->socket, recvs[i].ptr, recvs[i].length, 0 );
                              //printf("read %d\n",ret);
                              if (ret < 0) {
                                   if (WSAGetLastError() == 10035) {
                                        break;
                                   }
                                   D_PERROR( "Voodoo/Link: Failed to recv() data error %d!\n", WSAGetLastError() );
                    //               direct_mutex_unlock( &l->lock );
                                   return DR_IO;
                              }
          
                              recvs[i].done = (size_t) ret;
          
                              if (recvs[i].done < recvs[i].length)
                                   return DR_OK;

                              return DR_OK;
                         }
                    }
                    break;
     
               case WSA_WAIT_TIMEOUT:
                    //printf("<-- timeout\n");
                    return DR_TIMEOUT;
                    break;
     
               default:
                    D_ERROR( "Voodoo/Link: WaitForMultipleObjects() failed!\n" );
                    return DR_FAILURE;
          }
     }

//     direct_mutex_unlock( &l->lock );

     return DR_OK;
}
Beispiel #25
0
DirectResult
voodoo_link_init_local( VoodooLink *link,
                        const char *path,
                        bool        raw )
{
     DirectResult        ret;
     int                 err;
     struct sockaddr_un  addr;
     Link               *l;

     D_ASSERT( link != NULL );
     D_ASSERT( path != NULL );

     l = D_CALLOC( 1, sizeof(Link) );
     if (!l)
          return D_OOM();

     /* Create the client socket. */
     l->fd[0] = socket( AF_LOCAL, SOCK_STREAM, 0 );
     if (l->fd[0] < 0) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
          D_FREE( l );
          return ret;
     }
     l->fd[1] = l->fd[0];

#if !VOODOO_BUILD_NO_SETSOCKOPT
     if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );

     if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
#endif

     D_INFO( "Voodoo/Link: Connecting to '%s'...\n", path );


     memset( &addr, 0, sizeof(addr) );

     /* Bind the socket to the local port. */
     addr.sun_family = AF_UNIX;

     snprintf( addr.sun_path + 1, UNIX_PATH_MAX - 1, "%s", path );

     /* Connect to the server. */
     err = connect( l->fd[0], (struct sockaddr*) &addr, strlen(addr.sun_path+1)+1 + sizeof(addr.sun_family) );
     if (err) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
          close( l->fd[0] );
          D_FREE( l );
          return ret;
     }

     D_INFO( "Voodoo/Link: Connected.\n" );

     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );

     if (!raw) {
          link->code = 0x80008676;

          if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
               D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
               close( l->fd[0] );
               D_FREE( l );
               return DR_IO;
          }
     }
     D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );

     if (pipe( l->wakeup_fds ))
          return errno2result( errno );


     link->priv        = l;
     link->Close       = Close;
     link->Read        = Read;
     link->Write       = Write;
     link->SendReceive = SendReceive;
     link->WakeUp      = WakeUp;
     link->WaitForData = WaitForData;

     return DR_OK;
}
Beispiel #26
0
DirectResult
voodoo_link_init_connect( VoodooLink *link,
                          const char *hostname,
                          int         port,
                          bool        raw )
{
     int                 ret; 
     struct sockaddr_in  addr;
     Link               *l;

     D_INFO( "Voodoo/Link: Connecting to '%s:%d'...\n", hostname, port );

     StartWinsock();

     l = D_CALLOC( 1, sizeof(Link) );
     if (!l)
          return D_OOM();

     l->socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
     if (l->socket == INVALID_SOCKET) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
          D_FREE( l );
          return ret;
     }

     addr.sin_family      = AF_INET;
     addr.sin_addr.s_addr = inet_addr( hostname );
     addr.sin_port        = htons( port );

     ret = connect( l->socket, (const struct sockaddr*) &addr, sizeof(addr) );
     if (ret < 0) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
          // FIXME: how to close the socket?
          D_FREE( l );
          return ret;
     }

     direct_mutex_init( &l->lock );

     l->event  = WSACreateEvent();

     if (!raw) {
          link->code = 0x80008676;

          if (send( l->socket, (const char*) &link->code, sizeof(link->code), 0 ) != 4) {
               D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
               // FIXME: how to close the socket?
               D_FREE( l );
               return DR_IO;
          }
     }

     link->priv        = l;
     link->Close       = Close;
     link->Read        = Read;
     link->Write       = Write;
     link->SendReceive = SendReceive;
     link->WakeUp      = WakeUp;
     link->WaitForData = WaitForData;

     return DR_OK;
}
Beispiel #27
0
DFBResult
dfb_x11_image_init_handler( DFBX11 *x11, x11Image *image )
{
     Visual *visual;
     XImage *ximage;

     D_MAGIC_ASSERT( image, x11Image );

     if (!x11->use_shm)
          return DFB_UNSUPPORTED;

     /* Lookup visual. */
     visual = x11->visuals[DFB_PIXELFORMAT_INDEX(image->format)];
     if (!visual)
          return DFB_UNSUPPORTED;

     image->visual = visual;

     XLockDisplay( x11->display );

     ximage = XShmCreateImage( x11->display, image->visual, image->depth,
                               ZPixmap, NULL, &image->seginfo, image->width, image->height );
     if (!ximage) {
          D_ERROR( "X11/ShmImage: Error creating shared image (XShmCreateImage)!\n");
          XUnlockDisplay( x11->display );
          return DFB_FAILURE;
     }

     /* we firstly create our shared memory segment with the size we need, and
      correct permissions for the owner, the group and the world --> 0777 */
     image->seginfo.shmid = shmget( IPC_PRIVATE, 
                                    ximage->bytes_per_line * ximage->height,
                                    IPC_CREAT | 0777 );
     if (image->seginfo.shmid < 0)
          goto error;

     /* Then, we have to attach the segment to our process, and we let the
        function search the correct memory place --> NULL. It's safest ! */
     image->seginfo.shmaddr = shmat( image->seginfo.shmid, NULL, 0 );
     if (!image->seginfo.shmaddr)
          goto error_shmat;

     ximage->data = image->seginfo.shmaddr;

     /* We set the buffer in Read and Write mode */
     image->seginfo.readOnly = False;

     if (!XShmAttach( x11->display, &image->seginfo ))
          goto error_xshmattach;

     image->ximage = ximage;
     image->pitch  = ximage->bytes_per_line;

     image->pixmap = XShmCreatePixmap( x11->display, DefaultRootWindow(x11->display), ximage->data,
                                       &image->seginfo, image->width, image->height, image->depth );

     image->gc = XCreateGC( x11->display, image->pixmap, 0, NULL );

     XUnlockDisplay( x11->display );

     return DFB_OK;


error_xshmattach:
     shmdt( image->seginfo.shmaddr );

error_shmat:
     shmctl( image->seginfo.shmid, IPC_RMID, NULL );

error:
     XDestroyImage( ximage );

     XUnlockDisplay( x11->display );

     return DFB_FAILURE;
}
Beispiel #28
0
static int
ik_btr_open_create(bool create, char *args)
{
	bool		inplace = false;
	uint64_t	feats = 0;
	int		rc;

	if (!daos_handle_is_inval(ik_toh)) {
		D_ERROR("Tree has been opened\n");
		return -1;
	}

	if (create && args != NULL) {
		if (args[0] == '+') {
			feats = BTR_FEAT_UINT_KEY;
			args += 1;
		}
		if (args[0] == 'i') { /* inplace create/open */
			inplace = true;
			if (args[1] != IK_SEP) {
				D_ERROR("wrong parameter format %s\n", args);
				return -1;
			}
			args += 2;
		}

		if (args[0] != 'o' || args[1] != IK_SEP_VAL) {
			D_ERROR("incorrect format for tree order: %s\n", args);
			return -1;
		}

		ik_order = atoi(&args[2]);
		if (ik_order < BTR_ORDER_MIN || ik_order > BTR_ORDER_MAX) {
			D_ERROR("Invalid tree order %d\n", ik_order);
			return -1;
		}
	} else if (!create) {
		inplace = (ik_root->tr_class != 0);
		if (TMMID_IS_NULL(ik_root_mmid) && !inplace) {
			D_ERROR("Please create tree first\n");
			return -1;
		}
	}

	if (create) {
		D_PRINT("Create btree with order %d%s feats "DF_X64"\n",
			ik_order, inplace ? " inplace" : "", feats);
		if (inplace) {
			rc = dbtree_create_inplace(IK_TREE_CLASS, feats,
						   ik_order, ik_uma, ik_root,
						   &ik_toh);
		} else {
			rc = dbtree_create(IK_TREE_CLASS, feats, ik_order,
					   ik_uma, &ik_root_mmid, &ik_toh);
		}
	} else {
		D_PRINT("Open btree%s\n", inplace ? " inplace" : "");
		if (inplace) {
			rc = dbtree_open_inplace(ik_root,
						 ik_uma,
						 &ik_toh);
		} else {
			rc = dbtree_open(ik_root_mmid, ik_uma, &ik_toh);
		}
	}
	if (rc != 0) {
		D_ERROR("Tree %s failed: %d\n", create ? "create" : "open", rc);
		return -1;
	}
	return 0;
}
Beispiel #29
0
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     int         i, n;
     CoreScreen *screen;

     D_ASSERT( dfb_x11 == NULL );

     dfb_x11 = (DFBX11*) SHCALLOC( dfb_core_shmpool(core), 1, sizeof(DFBX11) );
     if (!dfb_x11) {
          D_ERROR( "DirectFB/X11: Couldn't allocate shared memory!\n" );
          return D_OOSHM();
     }

     dfb_x11_core = core;

     fusion_skirmish_init( &dfb_x11->lock, "X11 System", dfb_core_world(core) );

     fusion_call_init( &dfb_x11->call, call_handler, NULL, dfb_core_world(core) );

     dfb_surface_pool_initialize( core, &x11SurfacePoolFuncs, &dfb_x11->surface_pool );

     screen = dfb_screens_register( NULL, NULL, &x11PrimaryScreenFuncs );

     dfb_layers_register( screen, NULL, &x11PrimaryLayerFuncs );

     fusion_arena_add_shared_field( dfb_core_arena( core ), "x11", dfb_x11 );

     *data = dfb_x11;

     XInitThreads();

     dfb_x11->data_shmpool = dfb_core_shmpool_data( core );

     dfb_x11->display = XOpenDisplay(getenv("DISPLAY"));
     if (!dfb_x11->display) {
          D_ERROR("X11: Error in XOpenDisplay for '%s'\n", getenv("DISPLAY"));
          return DFB_INIT;
     }

     dfb_x11->screenptr = DefaultScreenOfDisplay(dfb_x11->display);
     dfb_x11->screennum = DefaultScreen(dfb_x11->display);

     for (i=0; i<dfb_x11->screenptr->ndepths; i++) {
          const Depth *depth = &dfb_x11->screenptr->depths[i];

          for (n=0; n<depth->nvisuals; n++) {
               Visual *visual = &depth->visuals[n];

               D_DEBUG( "X11/Visual: ID %02lu, depth %d, red 0x%06lx, green 0x%06lx, blue 0x%06lx, %d bits/rgb, %d entries\n",
                        visual->visualid, depth->depth,
                        visual->red_mask, visual->green_mask, visual->blue_mask,
                        visual->bits_per_rgb, visual->map_entries );

               switch (depth->depth) {
                    case 24:
                         if (visual->red_mask   == 0xff0000 &&
                             visual->green_mask == 0x00ff00 &&
                             visual->blue_mask  == 0x0000ff) {
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = visual;
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)]  = visual;
                         }
                         break;

                    case 16:
                         if (visual->red_mask   == 0xf800 &&
                             visual->green_mask == 0x07e0 &&
                             visual->blue_mask  == 0x001f)
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = visual;
                         break;

                    case 15:
                         if (visual->red_mask   == 0x7c00 &&
                             visual->green_mask == 0x03e0 &&
                             visual->blue_mask  == 0x001f)
                              dfb_x11->visuals[DFB_PIXELFORMAT_INDEX(DSPF_RGB555)] = visual;
                         break;
               }
          }
     }

     return DFB_OK;
}
Beispiel #30
0
static DFBResult
drmkmsInitScreen( CoreScreen           *screen,
                  CoreGraphicsDevice   *device,
                  void                 *driver_data,
                  void                 *screen_data,
                  DFBScreenDescription *description )
{
     DRMKMSData       *drmkms = driver_data;
     DRMKMSDataShared *shared = drmkms->shared;

     drmModeRes       *resources;
     drmModeConnector *connector = NULL;
     drmModeEncoder   *encoder   = NULL;
     uint32_t          crtc      = 0;

     int               i, j, k, l, found;

     description->caps = DSCCAPS_ENCODERS | DSCCAPS_OUTPUTS;
     description->encoders = 0;
     shared->enabled_crtcs = 0;

     direct_snputs( description->name, "DRMKMS Screen", DFB_SCREEN_DESC_NAME_LENGTH );

     resources = drmkms->resources;

     D_INFO( "DirectFB/DRMKMS: Got %d connectors, %d encoders\n", resources->count_connectors, resources->count_encoders );

     for (i = 0; i < resources->count_connectors; i++) {
          crtc = 0;
          connector = drmModeGetConnector( drmkms->fd, resources->connectors[i] );
          if (!connector)
               continue;

          if ((connector->connection == DRM_MODE_CONNECTED || connector->connection == DRM_MODE_UNKNOWNCONNECTION) && connector->count_modes > 0) {
               D_INFO( "DirectFB/DRMKMS: found connected connector id %d.\n", connector->connector_id );

               if (connector->encoder_id) {
                    D_INFO( "DirectFB/DRMKMS: connector %d is already bound to encoder %d.\n", connector->connector_id, connector->encoder_id );
                    encoder = drmModeGetEncoder(drmkms->fd, connector->encoder_id);
               }

               if (encoder)
                    crtc = encoder->crtc_id;

               if (crtc)
                    D_INFO( "DirectFB/DRMKMS: encoder %d is already bound to ctrc %d.\n", connector->encoder_id, encoder->crtc_id );
               else {
                    D_INFO( "DirectFB/DRMKMS: Seaching for appropriate encoder/crtc for connector %d.\n", connector->connector_id );
                    for (j = 0; j < resources->count_encoders; j++) {
                         int busy = 0;
                         encoder = drmModeGetEncoder( drmkms->fd, resources->encoders[j] );

                         if (encoder == NULL)
                              continue;

                         for (k=0; k<shared->enabled_crtcs; k++) {
                              if (drmkms->encoder[k]->encoder_id == encoder->encoder_id) {
                                   D_INFO( "DirectFB/DRMKMS: encoder %d is already in use by connector %d\n", encoder->encoder_id, drmkms->connector[k]->connector_id );
                                   busy = 1;
                              }
                         }

                         if (busy)
                              continue;

                         found = 0;
                         for (k = 0; k < resources->count_crtcs; k++) {
                              busy = 0;
                              if (!(encoder->possible_crtcs & (1 << k)))
                                   continue;

                              for (l=0; l<shared->enabled_crtcs; l++) {
                                   if (drmkms->encoder[l]->crtc_id == resources->crtcs[k])
                                        busy = 1;
                              }
                              if (busy)
                                   continue;


                              crtc = resources->crtcs[k];
                              D_INFO( "DirectFB/DRMKMS: using encoder %d and crtc %d for connector %d.\n", encoder->encoder_id, crtc, connector->connector_id );
                              found = 1;
                              break;
                         }

                         if (found)
                              break;
                    }
               }

               if (encoder && crtc) {
                    drmkms->connector[shared->enabled_crtcs] = connector;
                    drmkms->encoder[shared->enabled_crtcs] = encoder;
                    drmkms->encoder[shared->enabled_crtcs]->crtc_id = crtc;
                    shared->mode[shared->enabled_crtcs] = connector->modes[0];

                    shared->enabled_crtcs++;

                    if (!shared->multihead && !shared->mirror_outputs)
                         break;

                    if (shared->multihead && shared->enabled_crtcs > 1) {
                         dfb_layers_register( drmkms->screen, drmkms, drmkmsLayerFuncs );
                    }

               }
               else if (encoder)
                    drmModeFreeEncoder( encoder );

               encoder = NULL;
          }
          else
               drmModeFreeConnector( connector );
     }

     if (!shared->enabled_crtcs) {
          D_ERROR( "DirectFB/DRMKMS: No currently active connector found.\n");
          return DFB_INIT;
     }

     if (dfb_config->mode.width && dfb_config->mode.height) {
          drmModeModeInfo *mode  = drmkms_find_mode( 0, dfb_config->mode.width, dfb_config->mode.height, 0 );
          if (mode)
               shared->mode[0] = *mode;
     }

     if (shared->mirror_outputs || (dfb_config->mode.width && dfb_config->mode.height)) {
          for (int i=1; i<shared->enabled_crtcs; i++)
               shared->mode[i] = shared->mode[0];
     }

     if (shared->clone_outputs) {
          if (drmkms->encoder[0]->possible_clones) {
               for (i = 0; i < resources->count_crtcs; i++) {
                   if (drmkms->encoder[0]->possible_clones & (1 << i)) {
                         shared->cloned_connectors[shared->cloned_count++] = resources->connectors[0];
                         shared->cloned_connectors[shared->cloned_count++] = resources->connectors[1];
                         D_INFO( "DirectFB/DRMKMS: cloning on connector %d and %d enabled \n", resources->connectors[0], resources->connectors[1]);
                         break;
                   }
               }
               if (shared->cloned_count < 2) {
                    D_WARN( "DirectFB/DRMKMS: cloning is not possible on enough connectors, disabling.\n" );
                    shared->cloned_count = 0;
                    shared->clone_outputs = false;
               }
          }
          else {
                    D_WARN( "DirectFB/DRMKMS: cloning is not possible, disabling.\n" );
                    shared->clone_outputs = false;
          }
     }

     D_INFO( "DirectFB/DRMKMS: Default mode is %dx%d, we have %d modes in total\n", shared->mode[0].hdisplay, shared->mode[0].vdisplay, drmkms->connector[0]->count_modes );

     drmkms->resources = resources;
     drmkms->saved_crtc = drmModeGetCrtc( drmkms->fd, drmkms->encoder[0]->crtc_id );

     description->outputs   = shared->enabled_crtcs;
     description->encoders  = shared->enabled_crtcs;

     return DFB_OK;
}