Fix a fd leak in knotes backend (stupid me) and some cleanup in kaddrbook backend.
[beagle.git] / beagled / ThunderbirdQueryable / ThunderbirdInotify.cs
blob504e245d1a6aab9d9b116402628ee13ca98a9de3
1 //
2 // ThunderbirdInotify.cs. This class will sumnarize inotify events and raise an event every 30 seconds (to prevent inotify hammering)
3 //
4 // Copyright (C) 2006 Pierre Östlund
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
27 using System;
28 using System.IO;
29 using System.Collections;
31 using Beagle;
32 using Beagle.Util;
34 namespace Beagle.Daemon.ThunderbirdQueryable {
36 public class ThunderbirdInotify {
37 protected struct Event {
38 public Inotify.Watch Watch;
39 public string Path;
40 public string Subitem;
41 public string Srcpath;
42 public Inotify.EventType Type;
43 public long OldFileSize;
44 public long CurrentFileSize;
46 public Event (Inotify.Watch watch, string path, string subitem,
47 string srcpath, Inotify.EventType type, long old_size, long current_size)
49 this.Watch = watch;
50 this.Path = path;
51 this.Subitem = subitem;
52 this.Srcpath = srcpath;
53 this.Type = type;
54 this.OldFileSize = old_size;
55 this.CurrentFileSize = current_size;
59 private Queue queue;
61 public ThunderbirdInotify ()
63 queue = new Queue ();
65 GLib.Timeout.Add (30000, new GLib.TimeoutHandler (Process));
68 public void Watch (string path, Inotify.EventType type)
70 Inotify.Subscribe (path, OnInotify, type);
73 private void OnInotify (Inotify.Watch watch,
74 string path,
75 string subitem,
76 string srcpath,
77 Inotify.EventType type)
79 if (subitem == null)
80 return;
82 // Unsubscribe to directories that have been removed
83 if ((type & Inotify.EventType.Delete) != 0 && (type & Inotify.EventType.IsDirectory) != 0)
84 watch.Unsubscribe ();
86 lock (queue.SyncRoot) {
87 bool found = false;
88 for (int i = 0; i < queue.Count; i++) {
89 Event ev = (Event) queue.Dequeue ();
91 if (ev.Path == path && ev.Subitem == subitem && ev.Srcpath == srcpath) {
92 found = true;
93 ev.Type = (ev.Type | type);
94 queue.Enqueue (ev);
95 break;
98 queue.Enqueue (ev);
101 if (!found) {
102 queue.Enqueue (new Event (watch, path, subitem, srcpath,
103 type, -1, Thunderbird.GetFileSize (Path.Combine (path, subitem))));
108 private bool Process ()
110 Queue tmp = new Queue ();
112 lock (queue.SyncRoot) {
113 while (queue.Count > 0) {
114 Event ev = (Event) queue.Dequeue();
115 long size = Thunderbird.GetFileSize (Path.Combine (ev.Path, ev.Subitem));
117 if (Thunderbird.Debug) {
118 Logger.Log.Debug ("EVENT: {0} ({1}) [{2}, {3}]",
119 Path.Combine (ev.Path, ev.Subitem).ToString (), ev.Type, ev.CurrentFileSize, size);
122 if (size != ev.CurrentFileSize) {
123 ev.OldFileSize = ev.CurrentFileSize;
124 ev.CurrentFileSize = size;
125 tmp.Enqueue (ev);
126 continue;
129 OnInotifyEvent (ev);
132 while (tmp.Count > 0)
133 queue.Enqueue (tmp.Dequeue ());
136 return true;
139 protected virtual void OnInotifyEvent (Event ev)
141 if (InotifyEvent != null)
142 InotifyEvent (ev.Watch, ev.Path, ev.Subitem, ev.Srcpath, ev.Type);
145 public event Inotify.InotifyCallback InotifyEvent;