This file is indexed.

/usr/share/xul-ext/downthemall/modules/cothread.jsm is in xul-ext-downthemall 2.0.13-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/* You may find the license in the LICENSE file */

const EXPORTED_SYMBOLS = ['CoThread', 'CoThreadInterleaved', 'CoThreadListWalker'];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

const TYPE_REPEATING_SLACK = Ci.nsITimer.TYPE_REPEATING_SLACK;
const Timer = Components.Constructor('@mozilla.org/timer;1', 'nsITimer', 'initWithCallback');

// "Abstract" base c'tor
function CoThreadBase() {}
CoThreadBase.prototype = {
	_idx: 0,
	_ran: false,
	_finishFunc: null,

	init: function CoThreadBase_init(func, yieldEvery, thisCtx) {
		this._thisCtx = thisCtx ? thisCtx : this;
		
		// default to 1
		this._yieldEvery = typeof yieldEvery == 'number' ? Math.floor(yieldEvery) : 1;
		if (yieldEvery < 1) {
			throw Cr.NS_ERROR_INVALID_ARG;
		}
		
		if (typeof func != 'function' && !(func instanceof Function)) {
			throw Cr.NS_ERROR_INVALID_ARG;
		} 
		this._func = func;
		this.init = function() {};
	},
	
	run: function CoThreadBase_run(finishFunc) {
		if (this._ran) {
			throw new Error("You cannot run a CoThread/CoThreadListWalker instance more than once.");
		}
		this._finishFunc = finishFunc;
		this._ran = true;
		this._timer = new Timer(this, 10, TYPE_REPEATING_SLACK);		
	},
	
	QueryInterface: function CoThreadBase_QueryInterface(iid) {
		if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsITimerCallback)) {
			return this;
		}
		throw Cr.NS_ERROR_NO_INTERFACE;
	},
	
	notify: function CoThreadBase_notify() {
		let y = this._yieldEvery;
		let g = this._generator;
		let f = this._func;
		let ctx = this._thisCtx;
		let callf = this._callf;
		try {		
			for (let i = 0; i < y; ++i) {
				if (!callf(ctx, g.next(), this._idx++, f)) {
					throw 'complete';
				}
			}
		}
		catch (ex) {
			this.cancel();
		}
	},
	
	cancel: function CoThreadBase_cancel() {
		this._timer.cancel();
		if (this._finishFunc) {
			this._finishFunc.call(this._thisCtx);
		}		
	}
}

/**
 * Constructs a new CoThread (aka. pseudo-thread).
 * A CoThread will repeatedly call a specified function, but "breaking"
 * the operation temporarily after a certain amount of calls,
 * so that the main thread gets a chance to process any outstanding
 * events.
 * 
 * Example:
 *        Components.utils.import('resource://dta/cothread.jsm');
 *        new CoThread(
 *        	// What to do with each item?
 *          // Print it!
 *          function(count) document.write(count + "<br>") || (count < 30000),
 *          // When to turn over Control?
 *          // Each 1000 items
 *          1000
 *        ).run();
 *   
 * @param {Function} func Function to be called. Is passed call count as argument. Returning false will cancel the operation. 
 * @param {Number} yieldEvery Optional. After how many items control should be turned over to the main thread
 * @param {Object} thisCtx Optional. The function will be called in the scope of this object (or if omitted in the scope of the CoThread instance)
 */
function CoThread(func, yieldEvery, thisCtx) {
	this.init(func, yieldEvery, thisCtx);
	
	// fake generator so we may use a common implementation. ;)
	this._generator = (function() { for(;;) { yield null }; })();
}

CoThread.prototype = {
	__proto__: CoThreadBase.prototype,
	
	_callf: function CoThread__callf(ctx, item, idx, func) {
		return func.call(ctx, idx);
	}
}
/**
 * Constructs a new CoThreadInterleaved (aka. pseudo-thread).
 * The CoThread will process a interleaved function (generator)
 * 
 * Example:
 *        Components.utils.import('resource://dta/cothread.jsm');
 *        new CoThread(
 *          function(count) {
 *          	do_some();
 *          	yield true;
 *          	do_more();
 *          	yield true;
 *          	if (!do_even_more()) {
 *          		return;
 *          	}
 *          	do_last();
 *          },
 *          // When to turn over Control?
 *          // Each 2 items
 *          2
 *        ).run();
 *   
 * @param {Function} func Function to be called. Is passed call count as argument. Returning false will cancel the operation. 
 * @param {Number} yieldEvery Optional. After how many items control should be turned over to the main thread
 * @param {Object} thisCtx Optional. The function will be called in the scope of this object (or if omitted in the scope of the CoThread instance)
 */
function CoThreadInterleaved(generator, yieldEvery, thisCtx) {
		this.init(function() true, yieldEvery, thisCtx);
		this._generator = generator;
}
CoThreadInterleaved.prototype = {
	__proto__: CoThreadBase.prototype,
	
	_callf: function() true
};

/**
 * Constructs a new CoThreadListWalker (aka. pseudo-thread).
 * A CoThreadListWalker will walk a specified list and call a specified function
 * on each item, but "breaking" the operation temporarily after a
 * certain amount of processed items, so that the main thread may
 * process any outstanding events.
 * 
 * Example:
 *        Components.utils.import('resource://dta/cothread.jsm');
 *        new CoThreadListWalker(
 *        	// What to do with each item?
 *          // Print it!
 *          function(item, idx) document.write(item + "/" + idx + "<br>") || true,
 *          // What items?
 *          // 0 - 29999
 *          (function() { for (let i = 0; i < 30000; ++i) yield i; })(),
 *          // When to turn over Control?
 *          // Each 1000 items
 *          1000,
 *          null,
 *        ).run(function() alert('done'));
 *   
 * @param {Function} func Function to be called on each item. Is passed item and index as arguments. Returning false will cancel the operation. 
 * @param {Array/Generator} arrayOrGenerator Array or Generator object to be used as the input list 
 * @param {Number} yieldEvery Optional. After how many items control should be turned over to the main thread
 * @param {Object} thisCtx Optional. The function will be called in the scope of this object (or if omitted in the scope of the CoThread instance)
 */
function CoThreadListWalker(func, arrayOrGenerator, yieldEvery, thisCtx) {
	this.init(func, yieldEvery, thisCtx);
	
	if (arrayOrGenerator instanceof Array) {
		// make a generator
		this._generator = (i for each (i in arrayOrGenerator));
	}
	else {
		this._generator = arrayOrGenerator;
	}
	
	if (this._lastFunc && (typeof func != 'function' && !(func instanceof Function))) {
		throw Cr.NS_ERROR_INVALID_ARG;
	} 
}
 
CoThreadListWalker.prototype = {
	__proto__: CoThreadBase.prototype,
	_callf: function CoThreadListWalker__callf(ctx, item, idx, func) {
		return func.call(ctx, item, idx);
	}
}