Changeset 12403

Show
Ignore:
Timestamp:
05/26/08 03:08:14 (5 years ago)
Author:
topia
Message:

* add implementation of ->{mod_disposables}, ->add_module_object, ->remove_module_object.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/tiarra/branches/module-reload/main/ModuleManager.pm

    r12334 r12403  
    1010use warnings; 
    1111use UNIVERSAL; 
    12 #use RunLoop; 
     12use Scalar::Util qw(refaddr); 
    1313use Tiarra::SharedMixin qw(shared shared_manager); 
    1414use Tiarra::ShorthandConfMixin; 
     
    2323 
    2424sub _new { 
    25     shift->new(shift || RunLoop->shared); 
     25    shift->new(shift || do { require RunLoop && RunLoop->shared }); 
    2626} 
    2727 
     
    3737        mod_blacklist => {}, # 過去に正常動作しなかったモジュール。 
    3838        updated_once => 0, # 過去にupdate_modulesが実行された事があるか。 
     39        mod_disposables => {}, # モジュールに関連づけられているタイマーとか。アンロードした後で全部捨てる。 
    3940    }; 
    4041    bless $obj,$class; 
     
    160161} 
    161162 
     163sub add_module_object { 
     164    my $this = shift->_this; 
     165    my ($modname, @disposables) = @_; 
     166    $modname = ref($modname) || $modname; 
     167 
     168    push @{$this->{mod_disposables}->{$modname}}, @disposables; 
     169 
     170    $this; 
     171} 
     172 
     173sub remove_module_object { 
     174    my $this = shift->_this; 
     175    my ($modname, @disposables) = @_; 
     176    $modname = ref($modname) || $modname; 
     177 
     178    return unless $this->{mod_disposables}->{$modname}; 
     179 
     180    my %targets = map { refaddr($_) => 1 } @disposables; 
     181    @{$this->{mod_disposables}->{$modname}} = 
     182        grep { !$targets{refaddr($_)} } @{$this->{mod_disposables}->{$modname}}; 
     183 
     184    $this; 
     185} 
     186 
     187sub _destruct_module_object { 
     188    my $this = shift->_this; 
     189    my $module = shift; # module instance or module name 
     190    my $modname = ref($module) || $module; 
     191 
     192    my $arr = delete $this->{mod_disposables}->{$modname}; 
     193 
     194    return unless $arr; 
     195 
     196    foreach my $object (@$arr) { 
     197        eval { 
     198            $object->module_destruct($module); 
     199        }; if ($@) { 
     200            $this->_runloop->notify_error($@); 
     201        } 
     202    } 
     203 
     204    $this; 
     205} 
     206 
    162207sub update_modules { 
    163208    # +で指定されたモジュール一覧を読み、modulesを再構成する。 
     
    271316        # 先に destruct して回る 
    272317        foreach my $modname (reverse @mods_load_order) { 
    273             my $idx = $loaded_mods_idx{$modname}; 
    274             if (defined $idx) { 
     318            my $mod = $loaded_mods{$modname}; 
     319            if ($mod) { 
    275320                eval { 
    276                     $this->{modules}->[$idx]->destruct; 
     321                    $mod->destruct; 
    277322                }; if ($@) { 
    278323                    $this->_runloop->notify_error($@); 
    279324                } 
     325                $this->_destruct_module_object($mod); 
    280326            } else { 
    281327                eval { 
     
    284330                    $this->_runloop->notify_error($@); 
    285331                } 
     332                $this->_destruct_module_object($modname); 
    286333            } 
    287334        } 
     
    359406        # %loaded_modsに古い物が入っている場合は破棄した上、アンロードする。 
    360407        my $modname = $_; 
     408        my $mod = $loaded_mods{$modname}; 
    361409        $show_msg->("Module ".$modname." will be unloaded."); 
    362         if (defined $loaded_mods{$modname}) { 
     410        if (defined $mod) { 
    363411            eval { 
    364                 $loaded_mods{$modname}->destruct; 
     412                $mod->destruct; 
    365413            }; if ($@) { 
    366414                $this->_runloop->notify_error($@); 
    367415            } 
     416            $this->_destruct_module_object($mod); 
    368417        } 
    369418        $this->_unload($_); 
     
    526575        # 念のため古いやつは destruct しておく。エラーは無視。 
    527576        eval { $oldmod->destruct }; 
     577        $this->_destruct_module_object($oldmod); 
    528578        return undef; 
    529579    } 
     
    535585        # 念のため古いやつは destruct しておく。エラーは無視。 
    536586        eval { $oldmod->destruct }; 
     587        $this->_destruct_module_object($oldmod); 
    537588        return undef; 
    538589    } 
     
    655706                $key->destruct; 
    656707            }; 
     708            $this->_destruct_module_object($key); 
    657709 
    658710            $this->_runloop->notify_msg(