Changeset 9762

Show
Ignore:
Timestamp:
12/17/09 20:11:36 (9 months ago)
Author:
adamk
Message:

Landing new lock subsystem

Location:
trunk/Padre
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/Padre/Changes

    r9749 r9762  
    1616    - Fixed missing mime type guessing that caused new Padre documents to 
    1717      default always to Scintilla (AZAWAWI) 
     18    - Landed first phase of new multi-resource locking subsystem (ADAMK) 
    1819 
    19200.52 2009.12.14 
  • trunk/Padre/lib/Padre/Document/Perl.pm

    r9685 r9762  
    15181518                                $dialog->Destroy; 
    15191519                                return unless defined $replacement; 
     1520                                my $lock = $editor->main->lock('BUSY'); 
    15201521                                $doc->lexical_variable_replacement($replacement); 
    15211522                        }, 
  • trunk/Padre/lib/Padre/Lock.pm

    r9685 r9762  
    99sub new { 
    1010        my $class = shift; 
    11         my $self = bless {@_}, $class; 
     11        my $self  = bless { @_ }, $class; 
    1212 
    1313        # Enable the locks 
    14         if ( $self->{update} ) { 
     14        if ( $self->{UPDATE} ) { 
    1515                $self->{locker}->update_enable; 
    1616        } 
    17         if ( $self->{busy} ) { 
     17        if ( $self->{BUSY} ) { 
    1818                $self->{locker}->busy_enable; 
    1919        } 
     
    2222} 
    2323 
     24# Disable locking on destruction 
    2425sub DESTROY { 
    25  
    26         # Disable the locks 
    27         if ( $_[0]->{update} ) { 
     26        if ( $_[0]->{UPDATE} ) { 
    2827                $_[0]->{locker}->update_disable; 
    2928        } 
    30         if ( $_[0]->{busy} ) { 
     29        if ( $_[0]->{BUSY} ) { 
    3130                $_[0]->{locker}->busy_disable; 
    3231        } 
  • trunk/Padre/lib/Padre/Locker.pm

    r9685 r9762  
    11package Padre::Locker; 
     2 
     3=pod 
     4 
     5=head1 NAME 
     6 
     7Padre::Locker - The Padre Multi-Resource Lock Manager 
     8 
     9=cut 
    210 
    311use 5.008; 
     
    3240sub lock { 
    3341        my $self = shift; 
    34         return Padre::Lock->new( map { $_ => 1 } @_ ); 
     42        return Padre::Lock->new( 
     43                locker => $self, 
     44                map { $_ => 1 } @_ 
     45        ); 
    3546} 
    3647 
     
    6778 
    6879                # Locking for the first time 
    69                 $self->{busy_locker} = Wx::WindowDisabler->new; 
     80                $self->{busy_locker} = Wx::BusyCursor->new; 
    7081        } 
    7182        return; 
  • trunk/Padre/lib/Padre/Wx/Directory/SearchCtrl.pm

    r9685 r9762  
    518518        # Lock the gui here to make the updates look slicker 
    519519        # The locker holds the gui freeze until the update is done. 
    520         my $locker = $self->current->main->freezer; 
     520        my $lock = $self->current->main->lock('UPDATE'); 
    521521 
    522522        # Cleans the Directory Browser window to show the result 
  • trunk/Padre/lib/Padre/Wx/Directory/TreeCtrl.pm

    r9685 r9762  
    149149        # Lock the gui here to make the updates look slicker 
    150150        # The locker holds the gui freeze until the update is done. 
    151         my $locker = $self->main->freezer; 
     151        my $lock = $self->main->lock('UPDATE'); 
    152152 
    153153        # If the project have changed or the project root folder updates or 
  • trunk/Padre/lib/Padre/Wx/Main.pm

    r9749 r9762  
    128128        $self->{config} = $config; 
    129129 
     130        # Create the lock manager before any gui operations, 
     131        # so that we can do locking operations during startup. 
     132        $self->{locker} = Padre::Locker->new($self); 
     133 
    130134        # Determine the window title (needs ide & config) 
    131135        $self->set_title; 
    132136 
     137        # Remember where the editor started from, 
     138        # this could be handy later. 
     139        $self->{cwd} = Cwd::cwd(); 
     140 
     141        # There is a directory locking problem on Win32. 
     142        # If we open Padre from a directory and leave the Cwd cursor 
     143        # in that directory, then it can NEVER be deleted. 
    133144        # Having recorded the "current working directory" move 
    134         # the OS directory cursor away from this directory, so 
    135         # that Padre won't hold a lock on the current directory. 
    136         # If changing the directory fails, ignore errors (for now) 
    137         $self->{cwd} = Cwd::cwd(); 
    138         if (Padre::Constant::WIN32) { 
    139  
    140                 # Directory locking problem only exists on Win 
     145        # the OS directory cursor away from this starting directory, 
     146        # so that Padre won't hold an implicit OS lock on it. 
     147        # NOTE: If changing the directory fails, ignore errors for now, 
     148        #       since that means we have WAY bigger problems. 
     149        if ( Padre::Constant::WIN32 ) { 
    141150                chdir( File::HomeDir->my_home ); 
    142151        } 
     152 
     153        # Bootstrap locale support before we start fiddling with the GUI. 
     154        $self->{locale} = Padre::Locale::object(); 
    143155 
    144156        # A large complex application looks, frankly, utterly stupid 
    145157        # if it gets very small, or even mildly small. 
    146158        $self->SetMinSize( Wx::Size->new( 500, 400 ) ); 
    147  
    148         # Set the locale 
    149         $self->{locale} = Padre::Locale::object(); 
    150159 
    151160        # Drag and drop support 
     
    330339 
    331340        # GUI Elements 
     341        ide                 => 'ide', 
     342        config              => 'config', 
    332343        title               => 'title', 
    333         config              => 'config', 
    334         ide                 => 'ide', 
    335344        aui                 => 'aui', 
    336345        menu                => 'menu', 
     
    347356 
    348357        # Operating Data 
     358        locker     => 'locker', 
    349359        cwd        => 'cwd', 
    350360        search     => 'search', 
     
    619629=pod 
    620630 
    621 =head2 C<freezer> 
    622  
    623    my $locker = $main->freezer; 
    624  
    625 Create and return an automatic C<freeze> object that will C<thaw> on destruction. 
    626  
    627 =cut 
    628  
    629 sub freezer { 
    630         Wx::WindowUpdateLocker->new( $_[0] ); 
     631=head2 C<lock> 
     632 
     633  my $lock = $main->lock('UPDATE', 'BUSY', 'refresh_menu'); 
     634 
     635Create and return a guard object that holds resource locks of various types. 
     636 
     637The method takes a parameter list of the locks you wish to exist for the 
     638current scope. Special types of locks are provided in capitals, 
     639refresh/method locks are provided in lowercase. 
     640 
     641The C<UPDATE> lock creates a Wx repaint lock using the built in 
     642L<Wx::WindowUpdateLocker> class. 
     643 
     644You should use an update lock during GUI construction/modification to 
     645prevent screen flicker. As a side effect of not updating, the GUI changes 
     646happen B<significantly> faster as well. Update locks should only be held for 
     647short periods of time, as the operating system will begin to treat your\ 
     648application as "hung" if an update lock persists for more than a few 
     649seconds. In this situation, you may begin to see GUI corruption. 
     650 
     651The C<BUSY> lock creates a Wx "busy" lock using the built in 
     652L<Wx::WindowDisabler> class. 
     653 
     654You should use a busy lock during times when Padre has to do a long and/or 
     655complex operation in the foreground, or when you wish to disable use of any 
     656user interface elements until a background thread is finished. 
     657 
     658Busy locks can be held for long periods of time, however your users may 
     659start to suspect trouble if you do not provide any periodic feedback to them. 
     660 
     661Lowercase lock names are used to delay the firing of methods that will 
     662themselves generate GUI events you may want to delay until you are sure 
     663you want to rebuild the GUI. 
     664 
     665For example, opening a file will require a Padre::Wx::Main refresh call, 
     666which will itself generate more refresh calls on the directory browser, the 
     667function list, output window, menus, and so on. 
     668 
     669But if you open more than one file at a time, you don't want to refresh the 
     670menu for the first file, only to do it again on the second, third and 
     671fourth files. 
     672 
     673By creating refresh locks in the top level operation, you allow the lower 
     674level operation to make requests for parts of the GUI to be refreshed, but 
     675have the actual refresh actions delayed until the lock expires. 
     676 
     677This should make operations with a high GUI intensity both simpler and 
     678faster. 
     679 
     680The name of the lowercase MUST be the name of a Padre::Wx::Main method, 
     681which will be fired (with no params) when the method lock expires. 
     682 
     683=cut 
     684 
     685sub lock { 
     686        shift->locker->lock( @_ ); 
    631687} 
    632688 
     
    903959 
    904960        # Freeze during the refresh 
    905         my $guard   = $self->freezer; 
     961        my $lock    = $self->lock('UPDATE'); 
    906962        my $current = $self->current; 
    907963 
     
    12081264 
    12091265        # Do everything inside a freeze 
    1210         my $guard = $self->freezer; 
     1266        my $lock = $self->lock('UPDATE'); 
    12111267 
    12121268        # The biggest potential change is that the user may have a 
     
    28282884                # Lock both Perl and Wx-level updates 
    28292885                local $self->{_no_refresh} = 1; 
    2830                 my $guard = $self->freezer; 
     2886                my $lock = $self->lock('UPDATE'); 
    28312887 
    28322888                # If and only if there is only one current file, 
     
    33333389 
    33343390sub reload_all { 
    3335         my $self  = shift; 
    3336         my $skip  = shift; 
    3337         my $guard = $self->freezer; 
     3391        my $self = shift; 
     3392        my $skip = shift; 
     3393        my $lock = $self->lock('UPDATE'); 
    33383394 
    33393395        my @pages = $self->pageids; 
     
    38393895 
    38403896sub close_all { 
    3841         my $self  = shift; 
    3842         my $skip  = shift; 
    3843         my $guard = $self->freezer; 
     3897        my $self = shift; 
     3898        my $skip = shift; 
     3899        my $lock = $self->lock('UPDATE'); 
    38443900 
    38453901        my $manager = $self->{ide}->plugin_manager; 
     
    38993955        my $where    = shift; 
    39003956        my $notebook = $self->notebook; 
    3901         my $guard    = $self->freezer; 
     3957        my $lock     = $self->lock('UPDATE'); 
    39023958        foreach my $id ( reverse $self->pageids ) { 
    39033959                if ( $where->( $notebook->GetPage($id)->{Document} ) ) {