예제 #1
0
파일: ref.c 프로젝트: canalplus/r7oss
DirectResult
fusion_ref_up (FusionRef *ref, bool global)
{
     D_ASSERT( ref != NULL );

     D_DEBUG_AT( Fusion_Ref, "fusion_ref_up( %p [%d]%s )\n", ref, ref->multi.id, global ? " GLOBAL" : "" );

     while (ioctl (_fusion_fd( ref->multi.shared ), global ?
                   FUSION_REF_UP_GLOBAL : FUSION_REF_UP, &ref->multi.id))
     {
          switch (errno) {
               case EINTR:
                    continue;
               case EAGAIN:
                    return DR_LOCKED;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          if (global)
               D_PERROR ("FUSION_REF_UP_GLOBAL");
          else
               D_PERROR ("FUSION_REF_UP");

          return DR_FAILURE;
     }

     D_DEBUG_AT( Fusion_Ref, "  -> %d references now\n",
                 ioctl( _fusion_fd( ref->multi.shared ), FUSION_REF_STAT, &ref->multi.id ) );

     return DR_OK;
}
예제 #2
0
DirectResult
fusion_skirmish_notify( FusionSkirmish *skirmish )
{
     D_ASSERT( skirmish != NULL );

     if (skirmish->single) {
          pthread_cond_broadcast( &skirmish->single->cond );

          return DR_OK;
     }

     while (ioctl (_fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_NOTIFY, &skirmish->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;

               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
          }

          D_PERROR ("FUSION_SKIRMISH_NOTIFY");
          return DR_FUSION;
     }

     return DR_OK;
}
예제 #3
0
DirectResult
fusion_skirmish_destroy (FusionSkirmish *skirmish)
{
     D_ASSERT( skirmish != NULL );

     D_DEBUG_AT( Fusion_Skirmish, "fusion_skirmish_destroy( %p [%d] )\n", skirmish, skirmish->multi.id );
     
     if (skirmish->single) {
          int retval;

          pthread_cond_broadcast( &skirmish->single->cond );
          pthread_cond_destroy( &skirmish->single->cond );

          retval = pthread_mutex_destroy( &skirmish->single->lock );
          D_FREE( skirmish->single );

          return errno2result( retval );
     }

     while (ioctl( _fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_DESTROY, &skirmish->multi.id )) {
          switch (errno) {
               case EINTR:
                    continue;
                    
               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
          }

          D_PERROR ("FUSION_SKIRMISH_DESTROY");
          return DR_FUSION;
     }

     return DR_OK;
}
예제 #4
0
DirectResult
fusion_ref_set_name (FusionRef  *ref,
                     const char *name)
{
     FusionEntryInfo info;

     D_ASSERT( ref != NULL );
     D_ASSERT( name != NULL );

     info.type = FT_REF;
     info.id   = ref->multi.id;

     direct_snputs( info.name, name, sizeof(info.name) );

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_ENTRY_SET_INFO, &info)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EAGAIN:
                    return DR_LOCKED;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_ENTRY_SET_NAME");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #5
0
DirectResult
fusion_skirmish_swoop( FusionSkirmish *skirmish )
{
     D_ASSERT( skirmish != NULL );

     if (skirmish->single) {
          if (pthread_mutex_trylock( &skirmish->single->lock ))
               return errno2result( errno );

          skirmish->single->count++;

          return DR_OK;
     }

     while (ioctl (_fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_SWOOP, &skirmish->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;

               case EAGAIN:
                    return DR_BUSY;

               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
          }

          D_PERROR ("FUSION_SKIRMISH_SWOOP");
          return DR_FUSION;
     }

     return DR_OK;
}
예제 #6
0
파일: lock.c 프로젝트: kuii/dfbNEON
DirectResult
fusion_skirmish_wait( FusionSkirmish *skirmish, unsigned int timeout )
{
     FusionSkirmishWait wait;

     D_ASSERT( skirmish != NULL );

     wait.id         = skirmish->multi.id;
     wait.timeout    = timeout;
     wait.lock_count = 0;

     while (ioctl (_fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_WAIT, &wait)) {
          switch (errno) {
               case EINTR:
                    continue;

               case ETIMEDOUT:
                    return DR_TIMEOUT;

               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
          }

          D_PERROR ("FUSION_SKIRMISH_WAIT");
          return DR_FUSION;
     }

     return DR_OK;
}
예제 #7
0
DirectResult
fusion_skirmish_dismiss (FusionSkirmish *skirmish)
{
     D_ASSERT( skirmish != NULL );

     if (skirmish->single) {
          skirmish->single->count--;

          if (pthread_mutex_unlock( &skirmish->single->lock ))
               return errno2result( errno );

          return DR_OK;
     }

     while (ioctl (_fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_DISMISS, &skirmish->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;

               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
          }

          D_PERROR ("FUSION_SKIRMISH_DISMISS");
          return DR_FUSION;
     }

     return DR_OK;
}
예제 #8
0
DirectResult
fusion_ref_watch (FusionRef *ref, FusionCall *call, int call_arg)
{
     FusionRefWatch watch;

     D_ASSERT( ref != NULL );
     D_ASSERT( call != NULL );

     watch.id       = ref->multi.id;
     watch.call_id  = call->call_id;
     watch.call_arg = call_arg;

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_WATCH, &watch)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_WATCH");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #9
0
파일: lock.c 프로젝트: kuii/dfbNEON
DirectResult
fusion_skirmish_lock_count( FusionSkirmish *skirmish, int *lock_count )
{
     int data[2];

     D_ASSERT( skirmish != NULL );

     data[0] = skirmish->multi.id;
     data[1] = 0;

     while (ioctl (_fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_LOCK_COUNT, data)) {
           switch (errno) {
               case EINTR:
                    continue;

               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
           }

          D_PERROR ("FUSION_SKIRMISH_LOCK_COUNT");
          return DR_FUSION;
     }

     *lock_count = data[1];
     return DR_OK;
}
예제 #10
0
DirectResult
fusion_call_set_quota( FusionCall   *call,
                       FusionID      fusion_id,
                       unsigned int  limit )
{
     FusionCallSetQuota set_quota;

     D_DEBUG_AT( Fusion_Call, "%s( %p, fusion_id %lu, limit %u )\n", __FUNCTION__, call, fusion_id, limit );

     D_ASSERT( call != NULL );

     set_quota.call_id   = call->call_id;
     set_quota.fusion_id = fusion_id;
     set_quota.limit     = limit;

     while (ioctl (_fusion_fd( call->shared ), FUSION_CALL_SET_QUOTA, &set_quota)) {
          switch (errno) {
               case EINTR:
                    continue;
               default:
                    break;
          }

          D_PERROR ("FUSION_CALL_SET_QUOTA");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #11
0
DirectResult
fusion_ref_stat (FusionRef *ref, int *refs)
{
     int val;

     D_ASSERT( ref != NULL );
     D_ASSERT( refs != NULL );

     while ((val = ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_STAT, &ref->multi.id)) < 0) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_STAT");

          return DR_FAILURE;
     }

     *refs = val;

     return DR_OK;
}
예제 #12
0
DirectResult
fusion_ref_zero_trylock (FusionRef *ref)
{
     D_ASSERT( ref != NULL );

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_ZERO_TRYLOCK, &ref->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;
               case ETOOMANYREFS:
                    return DR_BUSY;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_ZERO_TRYLOCK");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #13
0
DirectResult
fusion_ref_catch (FusionRef *ref)
{
     D_ASSERT( ref != NULL );

     if (ref->multi.id == fusion_config->trace_ref) {
          D_INFO( "Fusion/Ref: 0x%08x catch\n", ref->multi.id );
          direct_trace_print_stack( NULL );
     }

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_CATCH, &ref->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_CATCH");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #14
0
DirectResult
fusion_ref_throw (FusionRef *ref, FusionID catcher)
{
     FusionRefThrow throw_;

     D_ASSERT( ref != NULL );

     if (ref->multi.id == fusion_config->trace_ref) {
          D_INFO( "Fusion/Ref: 0x%08x throw\n", ref->multi.id );
          direct_trace_print_stack( NULL );
     }

     throw_.id      = ref->multi.id;
     throw_.catcher = catcher;

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_THROW, &throw_)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_THROW");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #15
0
DirectResult
fusion_call_add_permissions( FusionCall            *call,
                             FusionID               fusion_id,
                             FusionCallPermissions  call_permissions )
{
     FusionEntryPermissions permissions;

     permissions.type        = FT_CALL;
     permissions.id          = call->call_id;
     permissions.fusion_id   = fusion_id;
     permissions.permissions = 0;

     if (call_permissions & FUSION_CALL_PERMIT_EXECUTE) {
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_CALL_EXECUTE );
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_CALL_EXECUTE2 );
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_CALL_EXECUTE3 );
     }

     while (ioctl( _fusion_fd( call->shared ), FUSION_ENTRY_ADD_PERMISSIONS, &permissions ) < 0) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/Call: FUSION_ENTRY_ADD_PERMISSIONS( id %d ) failed!\n", call->call_id );
               return DR_FAILURE;
          }
     }

     return DR_OK;
}
예제 #16
0
파일: call.c 프로젝트: ysei/uclinux-2
DirectResult
fusion_call_execute (FusionCall          *call,
                     FusionCallExecFlags  flags,
                     int                  call_arg,
                     void                *call_ptr,
                     int                 *ret_val)
{
     D_DEBUG_AT( Fusion_Call, "%s( %p, 0x%x, %d, %p )\n", __FUNCTION__, call, flags, call_arg, call_ptr );

     D_ASSERT( call != NULL );

     if (!call->handler)
          return DR_DESTROYED;

     D_DEBUG_AT( Fusion_Call, "  -> %s\n", direct_trace_lookup_symbol_at( call->handler ) );

     if (!(flags & FCEF_NODIRECT) && call->fusion_id == _fusion_id( call->shared )) {
          int                     ret;
          FusionCallHandlerResult result;

          result = call->handler( _fusion_id( call->shared ), call_arg, call_ptr, call->ctx, 0, &ret );

          if (result != FCHR_RETURN)
               D_WARN( "local call handler returned FCHR_RETAIN, need FCEF_NODIRECT" );

          if (ret_val)
               *ret_val = ret;
     }
     else {
          FusionCallExecute execute;

          execute.call_id  = call->call_id;
          execute.call_arg = call_arg;
          execute.call_ptr = call_ptr;
          execute.flags    = flags;

          while (ioctl( _fusion_fd( call->shared ), FUSION_CALL_EXECUTE, &execute )) {
               switch (errno) {
                    case EINTR:
                         continue;
                    case EINVAL:
//                         D_ERROR ("Fusion/Call: invalid call\n");
                         return DR_INVARG;
                    case EIDRM:
                         return DR_DESTROYED;
                    default:
                         break;
               }

               D_PERROR ("FUSION_CALL_EXECUTE");

               return DR_FAILURE;
          }

          if (ret_val)
               *ret_val = execute.ret_val;
     }

     return DR_OK;
}
예제 #17
0
DirectResult
fusion_call_destroy (FusionCall *call)
{
     D_DEBUG_AT( Fusion_Call, "%s( %p )\n", __FUNCTION__, call );

     D_ASSERT( call != NULL );
     D_ASSERT( call->handler != NULL || call->handler3 != NULL );

     if (direct_log_domain_check( &Fusion_Call )) // avoid call to direct_trace_lookup_symbol_at
          D_DEBUG_AT( Fusion_Call, "  -> %s\n", direct_trace_lookup_symbol_at( call->handler ) );

     while (ioctl (_fusion_fd( call->shared ), FUSION_CALL_DESTROY, &call->call_id)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
//FIXME: kernel module destroys calls from exiting process already                    D_ERROR ("Fusion/Call: invalid call\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_CALL_DESTROY");

          return DR_FAILURE;
     }

     call->handler = NULL;

     return DR_OK;
}
예제 #18
0
DirectResult
fusion_ref_inherit (FusionRef *ref, FusionRef *from)
{
     FusionRefInherit inherit;

     D_ASSERT( ref != NULL );
     D_ASSERT( from != NULL );

     inherit.id   = ref->multi.id;
     inherit.from = from->multi.id;

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_INHERIT, &inherit)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_INHERIT");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #19
0
DirectResult
fusion_call_get_owner( FusionCall *call,
                       FusionID   *ret_fusion_id )
{
     FusionCallGetOwner get_owner;

     D_DEBUG_AT( Fusion_Call, "%s( %p )\n", __FUNCTION__, call );

     D_ASSERT( call != NULL );
     D_ASSERT( ret_fusion_id != NULL );

     get_owner.call_id = call->call_id;

     while (ioctl (_fusion_fd( call->shared ), FUSION_CALL_GET_OWNER, &get_owner)) {
          switch (errno) {
               case EINTR:
                    continue;
               default:
                    break;
          }

          D_PERROR ("FUSION_CALL_GET_OWNER");

          return DR_FAILURE;
     }

     *ret_fusion_id = get_owner.fusion_id;

     return DR_OK;
}
예제 #20
0
DirectResult
fusion_call_set_name( FusionCall *call,
                      const char *name )
{
     FusionEntryInfo info;

     D_ASSERT( call != NULL );
     D_ASSERT( name != NULL );

     info.type = FT_CALL;
     info.id   = call->call_id;

     direct_snputs( info.name, name, sizeof(info.name) );

     while (ioctl (_fusion_fd( call->shared ), FUSION_ENTRY_SET_INFO, &info)) {
          perror("FUSION_ENTRY_SET_INFO");
          switch (errno) {
               case EINTR:
                    continue;
               case EAGAIN:
                    return DR_LOCKED;
               case EINVAL:
                    D_ERROR ("Fusion/Call: invalid call\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_ENTRY_SET_NAME");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #21
0
DirectResult
fusion_ref_destroy (FusionRef *ref)
{
     D_ASSERT( ref != NULL );

     D_DEBUG_AT( Fusion_Ref, "fusion_ref_destroy( %p [%d] )\n", ref, ref->multi.id );

     fusion_world_flush_calls( _fusion_world( ref->multi.shared ), 1 );

     while (ioctl (_fusion_fd( ref->multi.shared ), FUSION_REF_DESTROY, &ref->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_REF_DESTROY");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #22
0
DirectResult
fusion_property_lease (FusionProperty *property)
{
     D_ASSERT( property != NULL );

     while (ioctl (_fusion_fd( property->multi.shared ), FUSION_PROPERTY_LEASE, &property->multi.id)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EAGAIN:
                    return DR_BUSY;
               case EINVAL:
                    D_ERROR ("Fusion/Property: invalid property\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_PROPERTY_LEASE");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #23
0
파일: call.c 프로젝트: ysei/uclinux-2
DirectResult
fusion_call_destroy (FusionCall *call)
{
     D_DEBUG_AT( Fusion_Call, "%s( %p )\n", __FUNCTION__, call );

     D_ASSERT( call != NULL );
     D_ASSERT( call->handler != NULL );

     D_DEBUG_AT( Fusion_Call, "  -> %s\n", direct_trace_lookup_symbol_at( call->handler ) );

     while (ioctl (_fusion_fd( call->shared ), FUSION_CALL_DESTROY, &call->call_id)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Call: invalid call\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_CALL_DESTROY");

          return DR_FAILURE;
     }

     call->handler = NULL;

     return DR_OK;
}
예제 #24
0
DirectResult
fusion_ref_down (FusionRef *ref, bool global)
{
     D_ASSERT( ref != NULL );

     D_DEBUG_AT( Fusion_Ref, "fusion_ref_down( %p [%d]%s )\n", ref, ref->multi.id, global ? " GLOBAL" : "" );

     if (ref->multi.id == fusion_config->trace_ref) {
          D_INFO( "Fusion/Ref: 0x%08x down (%s)\n", ref->multi.id, global ? "global" : "local" );
          direct_trace_print_stack( NULL );
     }

     fusion_world_flush_calls( _fusion_world( ref->multi.shared ), 1 );

     while (ioctl (_fusion_fd( ref->multi.shared ), global ?
                   FUSION_REF_DOWN_GLOBAL : FUSION_REF_DOWN, &ref->multi.id))
     {
          switch (errno) {
               case EINTR:
                    continue;
               case EINVAL:
                    D_ERROR ("Fusion/Reference: invalid reference\n");
                    return DR_DESTROYED;
               default:
                    break;
          }

          if (global)
               D_PERROR ("FUSION_REF_DOWN_GLOBAL");
          else
               D_PERROR ("FUSION_REF_DOWN");

          return DR_FAILURE;
     }

// FIMXE: the following had to be commented out as the ref down may cause a ref watcher to free the memory of 'ref' (via ioctl)
#if 0
     if (ref->multi.shared)
          D_DEBUG_AT( Fusion_Ref, "  -> %d references now\n",
                      ioctl( _fusion_fd( ref->multi.shared ), FUSION_REF_STAT, &ref->multi.id ) );
     else
          D_DEBUG_AT( Fusion_Ref, "  -> destroyed\n" );
#endif

     return DR_OK;
}
예제 #25
0
DirectResult
fusion_ref_add_permissions( FusionRef            *ref,
                            FusionID              fusion_id,
                            FusionRefPermissions  ref_permissions )
{
     FusionEntryPermissions permissions;

     permissions.type        = FT_REF;
     permissions.id          = ref->multi.id;
     permissions.fusion_id   = fusion_id;
     permissions.permissions = 0;

     if (ref_permissions & FUSION_REF_PERMIT_REF_UNREF_LOCAL) {
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_UP );
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_DOWN );
     }

     if (ref_permissions & FUSION_REF_PERMIT_REF_UNREF_GLOBAL) {
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_UP_GLOBAL );
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_DOWN_GLOBAL );
     }

     if (ref_permissions & FUSION_REF_PERMIT_ZERO_LOCK_UNLOCK) {
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_ZERO_LOCK );
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_ZERO_TRYLOCK );
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_UNLOCK );
     }

     if (ref_permissions & FUSION_REF_PERMIT_WATCH)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_WATCH );

     if (ref_permissions & FUSION_REF_PERMIT_INHERIT)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_INHERIT );

     if (ref_permissions & FUSION_REF_PERMIT_DESTROY)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_DESTROY );

     if (ref_permissions & FUSION_REF_PERMIT_CATCH)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_CATCH );

     if (ref_permissions & FUSION_REF_PERMIT_THROW)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_REF_THROW );

     while (ioctl( _fusion_fd( ref->multi.shared ), FUSION_ENTRY_ADD_PERMISSIONS, &permissions ) < 0) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/Reactor: FUSION_ENTRY_ADD_PERMISSIONS( id %d ) failed!\n", ref->multi.id );
               return DR_FAILURE;
          }
     }

     return DR_OK;
}
예제 #26
0
DirectResult
fusion_skirmish_wait( FusionSkirmish *skirmish, unsigned int timeout )
{
     FusionSkirmishWait wait;

     D_ASSERT( skirmish != NULL );

     if (skirmish->single) {
          if (timeout) {
               struct timespec ts;
               struct timeval  tv;
               int             ret;

               gettimeofday( &tv, NULL );

               ts.tv_nsec = tv.tv_usec*1000 + (timeout%1000)*1000000;
               ts.tv_sec  = tv.tv_sec + timeout/1000 + ts.tv_nsec/1000000000;
               ts.tv_nsec = ts.tv_nsec % 1000000000;

               ret = pthread_cond_timedwait( &skirmish->single->cond, 
                                             &skirmish->single->lock, &ts );

               return (ret == ETIMEDOUT) ? DR_TIMEOUT : DR_OK;
          }

          return pthread_cond_wait( &skirmish->single->cond, &skirmish->single->lock );
     }

     wait.id         = skirmish->multi.id;
     wait.timeout    = timeout;
     wait.lock_count = 0;

     while (ioctl (_fusion_fd( skirmish->multi.shared ), FUSION_SKIRMISH_WAIT, &wait)) {
          switch (errno) {
               case EINTR:
                    continue;

               case ETIMEDOUT:
                    return DR_TIMEOUT;

               case EINVAL:
                    D_ERROR ("Fusion/Lock: invalid skirmish\n");
                    return DR_DESTROYED;
          }

          D_PERROR ("FUSION_SKIRMISH_WAIT");
          return DR_FUSION;
     }

     return DR_OK;
}
예제 #27
0
DirectResult
fusion_call_return3( FusionCall   *call,
                     unsigned int  serial,
                     void         *ptr,
                     unsigned int  length )
{
     FusionCallReturn3 call_ret;

     D_DEBUG_AT( Fusion_Call, "%s( %p, serial %u, ptr %p, length %u )\n", __FUNCTION__, call, serial, ptr, length );

     D_ASSERT( call != NULL );

     if (direct_log_domain_check( &Fusion_Call )) // avoid call to direct_trace_lookup_symbol_at
          D_DEBUG_AT( Fusion_Call, "  -> %s\n", direct_trace_lookup_symbol_at( call->handler ) );

     D_ASSUME( serial != 0 );
     if (!serial)
          return DR_UNSUPPORTED;

     call_ret.call_id = call->call_id;
     call_ret.serial  = serial;
     call_ret.ptr     = ptr;
     call_ret.length  = length;

     fusion_world_flush_calls( _fusion_world( call->shared ), 1 );

     while (ioctl (_fusion_fd( call->shared ), FUSION_CALL_RETURN3, &call_ret)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EIDRM:
                    D_WARN( "caller withdrawn (signal?)" );
                    return DR_NOCONTEXT;
               case EINVAL:
                    D_ERROR( "Fusion/Call: invalid call\n" );
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_CALL_RETURN3");

          return DR_FAILURE;
     }

     return DR_OK;
}
예제 #28
0
DirectResult
fusion_skirmish_add_permissions( FusionSkirmish            *skirmish,
                                 FusionID                   fusion_id,
                                 FusionSkirmishPermissions  skirmish_permissions )
{
     FusionEntryPermissions permissions;

     if (skirmish->single)
          return DR_OK;

     permissions.type        = FT_SKIRMISH;
     permissions.id          = skirmish->multi.id;
     permissions.fusion_id   = fusion_id;
     permissions.permissions = 0;

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_PREVAIL)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_PREVAIL );

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_SWOOP)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_SWOOP );

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_DISMISS)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_DISMISS );

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_LOCK_COUNT)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_LOCK_COUNT );

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_WAIT)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_WAIT );

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_NOTIFY)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_NOTIFY );

     if (skirmish_permissions & FUSION_SKIRMISH_PERMIT_DESTROY)
          FUSION_ENTRY_PERMISSIONS_ADD( permissions.permissions, FUSION_SKIRMISH_DESTROY );

     while (ioctl( _fusion_fd( skirmish->multi.shared ), FUSION_ENTRY_ADD_PERMISSIONS, &permissions ) < 0) {
          if (errno != EINTR) {
               D_PERROR( "Fusion/Reactor: FUSION_ENTRY_ADD_PERMISSIONS( id %d ) failed!\n", skirmish->multi.id );
               return DR_FAILURE;
          }
     }

     return DR_OK;
}
예제 #29
0
DirectResult
fusion_call_return( FusionCall   *call,
                    unsigned int  serial,
                    int           val )
{
     struct sockaddr_un addr;
     FusionCallReturn   callret;
     
     D_ASSERT( call != NULL );

     addr.sun_family = AF_UNIX;
     snprintf( addr.sun_path, sizeof(addr.sun_path), 
               "/tmp/.fusion-%d/call.%x.%x", call->shared->world_index, call->call_id, serial );
               
     callret.type = FMT_CALLRET;
     callret.val  = val;
               
     return _fusion_send_message( _fusion_fd( call->shared ), &callret, sizeof(callret), &addr );
}
예제 #30
0
파일: call.c 프로젝트: ysei/uclinux-2
DirectResult
fusion_call_return( FusionCall   *call,
                    unsigned int  serial,
                    int           val )
{
     FusionCallReturn call_ret;

     D_DEBUG_AT( Fusion_Call, "%s( %p, %u, %d )\n", __FUNCTION__, call, serial, val );

     D_ASSERT( call != NULL );

     D_DEBUG_AT( Fusion_Call, "  -> %s\n", direct_trace_lookup_symbol_at( call->handler ) );

     D_ASSUME( serial != 0 );
     if (!serial)
          return DR_UNSUPPORTED;

     call_ret.call_id = call->call_id;
     call_ret.val     = val;
     call_ret.serial  = serial;

     while (ioctl (_fusion_fd( call->shared ), FUSION_CALL_RETURN, &call_ret)) {
          switch (errno) {
               case EINTR:
                    continue;
               case EIDRM:
                    D_WARN( "caller withdrawn (signal?)" );
                    return DR_NOCONTEXT;
               case EINVAL:
                    D_ERROR( "Fusion/Call: invalid call\n" );
                    return DR_DESTROYED;
               default:
                    break;
          }

          D_PERROR ("FUSION_CALL_RETURN");

          return DR_FAILURE;
     }

     return DR_OK;
}