⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ref.c

📁 linux进程间高级通信的一个模块 是一个很不错的东西.
💻 C
📖 第 1 页 / 共 2 页
字号:
     return 0;}intfusion_ref_watch (FusionDev      *dev,                  int             id,                  int             call_id,                  int             call_arg){     int        ret;     FusionRef *ref;     ret = lock_ref (dev, false, id, &ref);     if (ret)          return ret;     if (ref->pid != current->pid) {          unlock_ref (ref);          return -EACCES;     }     if (ref->global + ref->local == 0) {          unlock_ref (ref);          return -EIO;     }     if (ref->watched) {          unlock_ref (ref);          return -EBUSY;     }     ref->watched  = true;     ref->call_id  = call_id;     ref->call_arg = call_arg;     wake_up_interruptible_all (&ref->wait);     unlock_ref (ref);     return 0;}intfusion_ref_inherit (FusionDev *dev,                    int        id,                    int        from_id){     int        ret;     FusionRef *ref;     FusionRef *from = NULL;     ret = lookup_ref (dev, false, id, &ref);     if (ret)          return ret;     if (down_interruptible (&ref->lock)) {          up (&dev->ref.lock);          return -EINTR;     }     ret = -EBUSY;     if (ref->inherited)          goto out;     ret = lock_ref (dev, true, from_id, &from);     if (ret)          goto out;     ret = add_inheritor( ref, from );     if (ret)          goto out;     ret = propagate_local( dev, ref, from->local );     if (ret)          goto out;     ref->inherited = from;out:     if (from)          unlock_ref (from);     unlock_ref (ref);     up (&dev->ref.lock);     return ret;}intfusion_ref_destroy (FusionDev *dev, int id){     int        ret;     FusionRef *ref;     ret = lookup_ref (dev, false, id, &ref);     if (ret)          return ret;     if (down_interruptible (&ref->lock)) {          up (&dev->ref.lock);          return -EINTR;     }     drop_inheritors( dev, ref );     if (ref->inherited)          remove_inheritor( ref, ref->inherited );     fusion_list_remove (&dev->ref.list, &ref->link);     wake_up_interruptible_all (&ref->wait);     up (&dev->ref.lock);     free_all_local (ref);     up (&ref->lock);     kfree (ref);     return 0;}voidfusion_ref_clear_all_local (FusionDev *dev, int fusion_id){     FusionLink *l;     down (&dev->ref.lock);     fusion_list_foreach (l, dev->ref.list) {          FusionRef *ref = (FusionRef *) l;          clear_local (dev, ref, fusion_id);     }     up (&dev->ref.lock);}/******************************************************************************/static intlookup_ref (FusionDev *dev, bool locked, int id, FusionRef **ret_ref){     FusionLink *l;     if (!locked && down_interruptible (&dev->ref.lock))          return -EINTR;     fusion_list_foreach (l, dev->ref.list) {          FusionRef *ref = (FusionRef *) l;          if (ref->id == id) {               *ret_ref = ref;               return 0;          }     }     if (!locked)          up (&dev->ref.lock);     return -EINVAL;}static intlock_ref (FusionDev *dev, bool locked, int id, FusionRef **ret_ref){     int         ret;     FusionRef *ref;     ret = lookup_ref (dev, locked, id, &ref);     if (ret)          return ret;     if (ref) {          fusion_list_move_to_front (&dev->ref.list, &ref->link);          if (down_interruptible (&ref->lock)) {               if (!locked)                    up (&dev->ref.lock);               return -EINTR;          }          if (!locked)               up (&dev->ref.lock);     }     *ret_ref = ref;     return 0;}static voidunlock_ref (FusionRef *ref){     up (&ref->lock);}static intadd_local (FusionRef *ref, int fusion_id, int add){     FusionLink *l;     LocalRef   *local;     fusion_list_foreach (l, ref->local_refs) {          local = (LocalRef *) l;          if (local->fusion_id == fusion_id) {               fusion_list_move_to_front( &ref->local_refs, l );               if (local->refs + add < 0)                    return -EIO;               local->refs += add;               return 0;          }     }     local = kmalloc (sizeof(LocalRef), GFP_KERNEL);     if (!local)          return -ENOMEM;     local->fusion_id = fusion_id;     local->refs      = add;     fusion_list_prepend (&ref->local_refs, &local->link);     return 0;}static voidclear_local (FusionDev *dev, FusionRef *ref, int fusion_id){     FusionLink *l;     down (&ref->lock);     if (ref->locked == fusion_id) {          ref->locked = 0;          wake_up_interruptible_all (&ref->wait);     }     fusion_list_foreach (l, ref->local_refs) {          LocalRef *local = (LocalRef *) l;          if (local->fusion_id == fusion_id) {               if (local->refs)                    propagate_local( dev, ref, - local->refs );               fusion_list_remove( &ref->local_refs, l );               kfree (l);               break;          }     }     up (&ref->lock);}static voidfree_all_local (FusionRef *ref){     FusionLink *l = ref->local_refs;     while (l) {          FusionLink *next = l->next;          kfree (l);          l = next;     }     ref->local_refs = NULL;}static voidnotify_ref (FusionDev *dev, FusionRef *ref){     if (ref->watched) {          FusionCallExecute execute;          execute.call_id  = ref->call_id;          execute.call_arg = ref->call_arg;          execute.call_ptr = NULL;          fusion_call_execute (dev, 0, &execute);     }     else          wake_up_interruptible_all (&ref->wait);}static intpropagate_local( FusionDev *dev, FusionRef *ref, int diff ){     FusionLink *l;     /* Recurse into inheritors. */     fusion_list_foreach (l, ref->inheritors) {          FusionRef *inheritor = ((Inheritor*) l)->ref;          if (down_interruptible( &inheritor->lock )) {               printk( KERN_ERR "fusion_ref: propagate_local() interrupted!\n" );               //return -EINTR;          }          propagate_local( dev, inheritor, diff );          up( &inheritor->lock );     }     /* Apply difference. */     ref->local += diff;     /* Notify zero count. */     if (ref->local + ref->global == 0)          notify_ref( dev, ref );     return 0;}static intadd_inheritor(FusionRef *ref, FusionRef *from){     Inheritor *inheritor;     inheritor = kmalloc (sizeof(Inheritor), GFP_KERNEL);     if (!inheritor)          return -ENOMEM;     inheritor->ref = ref;     fusion_list_prepend( &from->inheritors, &inheritor->link );     return 0;}static voidremove_inheritor(FusionRef *ref, FusionRef *from){     FusionLink *l;     down( &from->lock );     fusion_list_foreach (l, from->inheritors) {          Inheritor *inheritor = (Inheritor*) l;          if (inheritor->ref == ref) {               fusion_list_remove( &from->inheritors, &inheritor->link );               kfree( l );               break;          }     }     up( &from->lock );}static voiddrop_inheritors( FusionDev *dev, FusionRef *ref ){     FusionLink *l = ref->inheritors;     while (l) {          FusionLink *next      = l->next;          FusionRef  *inheritor = ((Inheritor*) l)->ref;          if (down_interruptible( &inheritor->lock )) {               printk( KERN_ERR "fusion_ref: drop_inheritors() interrupted!\n" );               //return;          }          propagate_local( dev, inheritor, - ref->local );          inheritor->inherited = NULL;          up( &inheritor->lock );          kfree (l);          l = next;     }     ref->inheritors = NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -