Hi Gonzalo,

I've investigated on my "deadlock" problem. It seems that this problem comes from GAMIN.
I explain:

I'm running a big (more than 50 aspx, ascx) web application. If I run a precompilation page (see the attached aspx.cs)
Mono, will compile about 20 pages, and will lock forever...
If you send a SIGQUIT to mod_mono_server you will obtain that some thread do :

- "" tid=0x0xb646bbb0 this=0x0x3893c0:
  - in (wrapper managed-to-native) System.IO.FAMWatcher:gamin_MonitorDirectory (System.IO.FAMConnection&,string,System.IO.FAMRequest&,intptr) <0x4>
- in (wrapper managed-to-native) System.IO.FAMWatcher:gamin_MonitorDirectory (System.IO.FAMConnection&,string,System.IO.FAMRequest&,intptr) <0xffffffbf>
  - in System.IO.FAMWatcher:FAMMonitorDirectory (System.IO.FAMConnection&,string,System.IO.FAMRequest&,intptr) <0x1f>
  - in System.IO.FAMWatcher:StartMonitoringDirectory (System.IO.FAMData,bool) <0x7d>
  - in System.IO.FAMWatcher:StartDispatching (System.IO.FileSystemWatcher) <0x192>
  - in System.IO.FileSystemWatcher:Start () <0x17>
  - in System.IO.FileSystemWatcher:set_EnableRaisingEvents (bool) <0x27>
  - in (wrapper remoting-invoke-with-check) System.IO.FileSystemWatcher:set_EnableRaisingEvents (bool) <0xffba2006>

So the gamin_MonitorDirectory will never end and block all the other thread...
The only way to force compilation contunation is to kill gam_server...
The compilation will continue, compile 5 page, and will block again!!

I've tried to remove gamin from my linux...
and suprise!!!

It work well, without gamin!

Is there a way to tell mono, not to use gamin, for FAMWatcher, even if gamin is installed?
My version of gamin, is the last one: 0.1.7

I'will try to do a test case with many aspx files, to show you the problem!

Thanks in advance

Le mardi 25 avril 2006 à 18:03 -0700, Gonzalo Paniagua Javier a écrit :
On Tue, 2006-04-25 at 18:25 +0200, Hubert FONGARNAND wrote:
> Hi Gonzalo,
> 
> It seems that i've another deadlock problem,
> but it's very hard to reproduce exactly
> I've send a SIGQUIT to mod_mono_server to do a thread dump :

Can you provide more data here? Specifically, the @Page or @Control
directive for the page/control that is being compiled and anything else
that helps reproducing the problem.

-Gonzalo

_______________________________________________
Ce message et les éventuels documents joints peuvent contenir des informations confidentielles.
Au cas où il ne vous serait pas destiné, nous vous remercions de bien vouloir le supprimer et en aviser immédiatement l'expéditeur. Toute utilisation de ce message non conforme à sa destination, toute diffusion ou publication, totale ou partielle et quel qu'en soit le moyen est formellement interdite.
Les communications sur internet n'étant pas sécurisées, l'intégrité de ce message n'est pas assurée et la société émettrice ne peut être tenue pour responsable de son contenu.
using System;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Net;
using System.IO;
using System.Globalization;
using System.Web.Security;

namespace IntranetAdmin
{
	/// <summary>
	/// Description résumée de PreCompile.
	/// </summary>
	public class PreCompile : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.Label Label4;
		protected System.Web.UI.WebControls.Panel pnlWarning;
	

		System.Net.Cookie biscuit=null;

		private void Page_Load(object sender, System.EventArgs e)
		{
			Server.ScriptTimeout=600;
			Response.Clear();
			Response.Write(@"<HTML>
	<HEAD>
		<title>PreCompile</title>
		<meta http-equiv='Content-Type' content='text/html;charset=utf-8'>
		<LINK href='General.css' type='text/css' rel='stylesheet'>
	</HEAD>
	<body>");
			//Création du cookie d'authentification temporaire
			FormsAuthenticationTicket ticketauth = new FormsAuthenticationTicket(1,"PreCompileDummy",DateTime.Now,DateTime.Now.AddHours(1),false,"fr"+"|"+"PreCompileDummyId");
			string cryptedTicket = FormsAuthentication.Encrypt(ticketauth);
			biscuit = new System.Net.Cookie(FormsAuthentication.FormsCookieName,cryptedTicket);			
			biscuit.Domain="localhost";
			//Compilation
			PreCompileAspx();
			Response.Write("<BR><BR>Compilation terminée.");
			Response.Write(@"</body></html>");
			Response.End();
		}

		/// <summary>
		/// PreCompile all ASPX pages for the current application.
		/// </summary>
		public void PreCompileAspx()
		{
			string rootDirectory = Request.PhysicalApplicationPath;
			Response.Write("Server path is >> " + rootDirectory);
			string url = Request.RawUrl;
			Response.Write("<br>Virtual path is >> " + url);
			//Get the virtual root directory.
			int index = url.LastIndexOf('/');
			string virtualDirectory = url.Substring(0,index+1);
			Response.Write("<br>Virtual directory is >> " + virtualDirectory + "<br><br>");

			ArrayList arrayList = GenerateUriList(rootDirectory,"http://localhost"; + virtualDirectory);
			TimeSpan totalSeconds=new TimeSpan(0);
			foreach(string uri in arrayList)
			{
				DateTime t=DateTime.Now;
				Response.Write("<br>Compiling ASPX resource >>> " + uri);				
				Response.Flush();
				FireRequest(uri);
				DateTime t2=DateTime.Now;
				TimeSpan s=t2-t;				
				Response.Write("<br>Compilation time >>> " + s.TotalSeconds.ToString()+" seconds.");
				Response.Flush();
				totalSeconds+=s;
			}

			Response.Write("<br>Total compilation time : " + totalSeconds.TotalSeconds.ToString()+" seconds.");
		}

		/// <summary>
		/// Loops thru the files on the server hard-disk and creates URI's to fire requests to.
		/// </summary>
		/// <param name="directory">The server local directory path</param>
		/// <param name="rootUri">The virtual ROOT path</param>
		/// <returns>ArrayList of all URL's of ASPX files in that application root folder</returns>
		public static ArrayList GenerateUriList(string directory, string rootUri)
		{
			ArrayList arrayList = GetAllFiles(directory,"*.aspx",true);
			ArrayList finalList = new ArrayList(arrayList.Count);
			foreach(string str in arrayList)
			{
				string uri = str.Replace(directory,rootUri);
				uri = uri.Replace(@"\","/");
				uri = uri + "?PreCompile=true";
				finalList.Add(uri);
			}
			return finalList;
		}

		/// <summary>
		/// Simulate a HTTP request. Make the request to 'localhost' as this file is present on the server.
		/// </summary>
		/// <param name="uri">The URL to make the request to.</param>
		public void FireRequest(string uri)
		{
			HttpWebRequest myHttpWebRequest = null;
			HttpWebResponse myHttpWebResponse = null;


			try
			{
				myHttpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
				myHttpWebRequest.CookieContainer=new CookieContainer();
				myHttpWebRequest.CookieContainer.Add(biscuit);
				myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 
			}
			catch(Exception ex)
			{
				Console.WriteLine("Request for uri faided>>" + ex);
			}
			finally
			{
				try{myHttpWebResponse.Close();}
				catch(Exception ignored){}
			}
		}

		/// <summary>
		/// Gets a list of all files in a directory. Also recursively..:)
		/// </summary>
		/// <param name="directory">The name/path of the directory </param>
		/// <param name="filter">The filter on files returned. For e.g. only text files, pass "*.txt". 
		/// Pass null if no specific filter is required.</param>
		/// <param name="getFilesInSubDirs">Whether to search for sub-directories recursively or not.</param>
		/// <returns></returns>
		public static ArrayList GetAllFiles(string directory,string filter,bool getFilesInSubDirs)
		{
			ArrayList totalFilesList = new ArrayList(10);

			string[] files = null;
			if(filter == null)
			{
				files = Directory.GetFiles(directory);
			}
			else
			{
				files = Directory.GetFiles(directory,filter);
			}
			totalFilesList.AddRange(files);//add all files in that current folder.

			if(getFilesInSubDirs)
			{
				//Check if the current directory has sub-directories
				string[] subDirs = Directory.GetDirectories(directory);
				//if yes, then call recursive functions..
				if(subDirs.Length > 0)
				{
					//now look for all files in current folder's sub-dir's.
					foreach(string subDir in subDirs)
					{
						ArrayList tempArrayList = GetAllFiles(subDir,filter,getFilesInSubDirs);
						totalFilesList.AddRange(tempArrayList);
					}
				}
			}
			return totalFilesList;
		}

		#region Code généré par le Concepteur Web Form
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN : Cet appel est requis par le Concepteur Web Form ASP.NET.
			//
			InitializeComponent();
			base.OnInit(e);
		}
		
		/// <summary>
		/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas
		/// le contenu de cette méthode avec l'éditeur de code.
		/// </summary>
		private void InitializeComponent()
		{    
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion
	}
}
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to