if (dothrow)
throw new HttpException (404, "The file '" + virtualPath + "' does not exist.");
}
-
+
+ const int ticketLockTimeout = 20000;
+ const int ticketLockAttempts = 3;
static void BuildAssembly (VirtualPath virtualPath)
{
AssertVirtualPathExists (virtualPath);
object ticket;
bool acquired;
+ bool locked = false;
string virtualDir = virtualPath.Directory;
BuildKind buildKind = BuildKind.Unknown;
bool kindPushed = false;
acquired = AcquireCompilationTicket (virtualDir, out ticket);
try {
- Monitor.Enter (ticket);
+ int attempts = ticketLockAttempts;
+ while (attempts-- > 0) {
+ if (Monitor.TryEnter (ticket, ticketLockTimeout)) {
+ locked = true;
+ break;
+ }
+ }
+ if (!locked)
+ throw new HttpException (500, "Failed to acquire compilation lock for virtual path '" + virtualPath + "'.");
+
lock (buildCacheLock) {
if (buildCache.ContainsKey (vpAbsolute))
return;
recursiveBuilds.Pop ();
}
}
-
- Monitor.Exit (ticket);
- if (acquired)
- ReleaseCompilationTicket (virtualDir);
+
+ if (locked) {
+ Monitor.Exit (ticket);
+ if (acquired)
+ ReleaseCompilationTicket (virtualDir);
+ }
}
}
+2008-12-05 Marek Habersack <mhabersack@novell.com>
+
+ * BuildManager.cs: attempt to enter the compilation critical
+ section with a timeout up to 3 times before giving up. This avoids
+ deadlocks in situations where there are two virtual directores
+ each containing user controls referencing user controls from the
+ other directory.
2008-12-02 Gonzalo Paniagua Javier <gonzalo@novell.com>