Eskil

Check-in [a36a8fc470]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Handle vfs in threads
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | thread
Files: files | file ages | folders
SHA1: a36a8fc470d753f2524ff9d4219baa1acb26d4f1
User & Date: peter 2016-08-06 18:59:31.488
Context
2016-08-06
18:59
Handle vfs in threads Leaf check-in: a36a8fc470 user: peter tags: thread
2016-08-03
17:45
Merge from trunk check-in: d1d44e3aed user: peter tags: thread
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/dirdiff.tcl.
1362
1363
1364
1365
1366
1367
1368






1369
1370
1371
1372
1373
1374
1375
            }
            set ::dirdiff(leftDir) $d1
            if {$rev2 ne ""} {
                .dirdiffX.l2 configure -text "and rev $rev2..."
                update
                set d2 [eskil::rev::${type}::mount $fullname $rev2]
                set ::dirdiff(rightDir) $d2






            }
            destroy .dirdiffX
        }
    }

    destroy .dirdiff
    DirDiff .dirdiff







>
>
>
>
>
>







1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
            }
            set ::dirdiff(leftDir) $d1
            if {$rev2 ne ""} {
                .dirdiffX.l2 configure -text "and rev $rev2..."
                update
                set d2 [eskil::rev::${type}::mount $fullname $rev2]
                set ::dirdiff(rightDir) $d2
            }
            # VcsVfs mounts are thread local. Transfer them to any worker thread
            foreach tid $::eskil(threads) {
                .dirdiffX.l2 configure -text "and rev $rev2... (+thread)"
                update
                vcsvfs::transfer $tid
            }
            destroy .dirdiffX
        }
    }

    destroy .dirdiff
    DirDiff .dirdiff
Changes to src/startup.tcl.
79
80
81
82
83
84
85

86
87
88
89
90
91

92
93
94

95
96
97
98
99
100
101
    if {[file exists $::eskil(thisDir)/../version.txt]} {
        set ch [open $::eskil(thisDir)/../version.txt]
        set ::eskil(diffver) [string trim [read $ch 100]]
        close $ch
    }

    ##nagelfar syntax SubEval c

    if {[catch {package require Thread}]} {
        interp create _tinterp_
        interp alias {} SubEval _tinterp_ eval
    } else {
        set tid [thread::create -preserved]
        interp alias {} SubEval {} thread::send $tid

    }
    SubEval [list set ::auto_path $::auto_path]
    SubEval [list set ::argv0 $::argv0]

    SubEval [list set ::starkit::topdir $::starkit::topdir]
    SubEval {
        if {![file isdir $::starkit::topdir]} {
            vfs::mk4::Mount $::starkit::topdir $::starkit::topdir
        }
    }
    SubEval [list array set ::eskil [array get ::eskil]]







>






>



>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
    if {[file exists $::eskil(thisDir)/../version.txt]} {
        set ch [open $::eskil(thisDir)/../version.txt]
        set ::eskil(diffver) [string trim [read $ch 100]]
        close $ch
    }

    ##nagelfar syntax SubEval c
    set ::eskil(threads) {}
    if {[catch {package require Thread}]} {
        interp create _tinterp_
        interp alias {} SubEval _tinterp_ eval
    } else {
        set tid [thread::create -preserved]
        interp alias {} SubEval {} thread::send $tid
        lappend ::eskil(threads) $tid
    }
    SubEval [list set ::auto_path $::auto_path]
    SubEval [list set ::argv0 $::argv0]
    SubEval [list namespace eval ::starkit {}]
    SubEval [list set ::starkit::topdir $::starkit::topdir]
    SubEval {
        if {![file isdir $::starkit::topdir]} {
            vfs::mk4::Mount $::starkit::topdir $::starkit::topdir
        }
    }
    SubEval [list array set ::eskil [array get ::eskil]]
Changes to src/vcsvfs.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#----------------------------------------------------------------------
#  Virtual File System for Version Control Systems
#
#  Copyright (c) 2014-2015, Peter Spjuth
#
#  License for vcsvfs package: Same as for Tcl
#----------------------------------------------------------------------

package require vfs
package provide vcsvfs 0.2

namespace eval vcsvfs {
    variable DataRefChan
    variable mpoints {}
    namespace eval fossil {}
    namespace eval svn {}
    namespace eval git {}



|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#----------------------------------------------------------------------
#  Virtual File System for Version Control Systems
#
#  Copyright (c) 2014-2016, Peter Spjuth
#
#  License for vcsvfs package: Same as for Tcl
#----------------------------------------------------------------------

package require vfs
package provide vcsvfs 0.3

namespace eval vcsvfs {
    variable DataRefChan
    variable mpoints {}
    namespace eval fossil {}
    namespace eval svn {}
    namespace eval git {}
748
749
750
751
752
753
754
755
756



757


758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773


774
775

776
777
778
779
780
781
782
            # Read-only, always error
        }
    }
    vfs::filesystem posixerror $::vfs::posix(EACCES)
    return -code error $::vfs::posix(EACCES)
}

# Transfer a VcsVfs mount point to another Thread.
# TclVfs mounts are thread local.



# If no mount point is given, tranfer all current mount points


proc vcsvfs::transfer {threadId {mountpoint {}}} {
    variable mpoints
    thread::send -async $threadId "package require vcsvfs"
    if {$mountpoint eq ""} {
        set data $mpoints
    } else {
        set data [dict create $mountpoint [dict get $mpoints $mountpoint]]
    }
    # Data might be large. Is that a problem? Is there a more efficient way?
    thread::send -async $threadId [list vcsvfs::Receive $data]
}

# Create mount(s) from received data
proc vcsvfs::Receive {data} {
    variable mpoints
    foreach mountpoint [dict keys $data] {


        dict set mpoints $mountpoint [dict get $data $mountpoint]
        vfs::filesystem mount $mountpoint [list vcsvfs::Vfs]

    }
}

##################################################################
# Test structure
##################################################################
if 0 {







|
|
>
>
>
|
>
>
















>
>
|
|
>







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
            # Read-only, always error
        }
    }
    vfs::filesystem posixerror $::vfs::posix(EACCES)
    return -code error $::vfs::posix(EACCES)
}

# Transfer VcsVfs mount point(s) to another Thread.
# TclVfs (which VcsVfs is based on) mounts are thread local
#
# threadId:   Thread id as created by Thread package
# mountpoint: Mount point to transfer.
#             If no mount point is given, tranfer all current mount points
#
# Returns: None
proc vcsvfs::transfer {threadId {mountpoint {}}} {
    variable mpoints
    thread::send -async $threadId "package require vcsvfs"
    if {$mountpoint eq ""} {
        set data $mpoints
    } else {
        set data [dict create $mountpoint [dict get $mpoints $mountpoint]]
    }
    # Data might be large. Is that a problem? Is there a more efficient way?
    thread::send -async $threadId [list vcsvfs::Receive $data]
}

# Create mount(s) from received data
proc vcsvfs::Receive {data} {
    variable mpoints
    foreach mountpoint [dict keys $data] {
        # Avoid duplicates
        if {![dict exists $mpoints $mountpoint]} {
            dict set mpoints $mountpoint [dict get $data $mountpoint]
            vfs::filesystem mount $mountpoint [list vcsvfs::Vfs]
        }
    }
}

##################################################################
# Test structure
##################################################################
if 0 {