[70174] trunk/base/src
jmr at macports.org
jmr at macports.org
Sat Jul 31 05:57:12 PDT 2010
Revision: 70174
http://trac.macports.org/changeset/70174
Author: jmr at macports.org
Date: 2010-07-31 05:57:09 -0700 (Sat, 31 Jul 2010)
Log Message:
-----------
acquire an exclusive lock when making registry modifications (#19935)
Modified Paths:
--------------
trunk/base/src/macports1.0/macports.tcl
trunk/base/src/port/port.tcl
trunk/base/src/registry2.0/registry.tcl
Modified: trunk/base/src/macports1.0/macports.tcl
===================================================================
--- trunk/base/src/macports1.0/macports.tcl 2010-07-31 12:42:05 UTC (rev 70173)
+++ trunk/base/src/macports1.0/macports.tcl 2010-07-31 12:57:09 UTC (rev 70174)
@@ -1584,7 +1584,7 @@
# Before we build the port, we must build its dependencies.
set dlist {}
if {[macports::_target_needs_deps $target]} {
-
+ registry::exclusive_lock
# see if we actually need to build this port
if {($target != "activate" && $target != "install") ||
![$workername eval registry_exists \$name \$version \$revision \$portvariants]} {
@@ -1638,6 +1638,7 @@
} else {
set result [dlist_eval $dlist _mportinstalled [list _mportexec "activate"]]
}
+ registry::exclusive_unlock
if {$result != {}} {
set errstring "The following dependencies failed to build:"
Modified: trunk/base/src/port/port.tcl
===================================================================
--- trunk/base/src/port/port.tcl 2010-07-31 12:42:05 UTC (rev 70173)
+++ trunk/base/src/port/port.tcl 2010-07-31 12:57:09 UTC (rev 70174)
@@ -4066,6 +4066,24 @@
}
}
+# acquire exclusive registry lock for actions that need it
+# returns 1 if locked, 0 otherwise
+proc lock_reg_if_needed {action} {
+ switch -- $action {
+ activate -
+ deactivate -
+ select -
+ setrequested -
+ unsetrequested -
+ upgrade -
+ uninstall -
+ install {
+ registry::exclusive_lock
+ return 1
+ }
+ }
+ return 0
+}
proc process_cmd { argv } {
global cmd_argc cmd_argv cmd_argn
@@ -4092,7 +4110,8 @@
while { [moreargs] } { advance }
break
}
-
+
+ set locked [lock_reg_if_needed $action]
# Always start out processing an action in current_portdir
cd $current_portdir
@@ -4155,6 +4174,11 @@
# execute the action
set action_status [$action_proc $action $portlist [array get global_options]]
+ # unlock if needed
+ if {$locked} {
+ registry::exclusive_unlock
+ }
+
# semaphore to exit
if {$action_status == -999} break
}
Modified: trunk/base/src/registry2.0/registry.tcl
===================================================================
--- trunk/base/src/registry2.0/registry.tcl 2010-07-31 12:42:05 UTC (rev 70173)
+++ trunk/base/src/registry2.0/registry.tcl 2010-07-31 12:57:09 UTC (rev 70174)
@@ -39,6 +39,8 @@
package require msgcat
namespace eval registry {
+ variable lockfd
+ variable nlocked 0
# Begin creating a new registry entry for the port version_revision+variant
# This process assembles the directory name and creates a receipt dlist
@@ -387,6 +389,49 @@
return [${macports::registry.format}::write_dep_map $args]
}
+# acquire exclusive lock on registry, do this before modifying it or reading
+# any info which will affect a decision on what to modify
+proc exclusive_lock {} {
+ global macports::registry.path
+ variable lockfd
+ variable nlocked
+ incr nlocked
+ if {$nlocked > 1} {
+ return
+ }
+ set lockpath [file join ${registry.path} registry .registry.lock]
+ if {![info exists lockfd]} {
+ set lockfd [::open $lockpath w]
+ }
+ if {[catch {flock $lockfd -exclusive -noblock} result]} {
+ if {$result == "EAGAIN"} {
+ ui_msg "Waiting for lock on $lockpath"
+ flock $lockfd -exclusive
+ } elseif {$result == "EOPNOTSUPP"} {
+ # Locking not supported, just return
+ ui_debug "flock not supported, not locking registry"
+ } else {
+ return -code error "$result obtaining lock on $lockpath"
+ }
+ }
+}
+
+# release exclusive lock on registry, do this when done writing to it
+proc exclusive_unlock {} {
+ variable lockfd
+ variable nlocked
+ incr nlocked -1
+ if {$nlocked > 0} {
+ return
+ } elseif {$nlocked < 0} {
+ ui_warn "exclusive_unlock called more often than exclusive_lock!"
+ }
+ if {[info exists lockfd]} {
+ # not much point trying to handle errors
+ catch {flock $lockfd -unlock}
+ }
+}
+
# upgrade flat receipts to registry2.0 sqlite db
proc convert_to_sqlite {} {
set ilist [receipt_flat::installed "" ""]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20100731/9bf8c4b8/attachment.html>
More information about the macports-changes
mailing list