Skip to content

Commit 2ced71c

Browse files
authored
FELIX-6516 - Remove synchronization on Integer and replace it with a dedicated StartLevelRequest object (#134)
1 parent f8f0def commit 2ced71c

1 file changed

Lines changed: 46 additions & 26 deletions

File tree

framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,9 @@ class FrameworkStartLevelImpl implements FrameworkStartLevel, Runnable
3434
{
3535
static final String THREAD_NAME = "FelixStartLevel";
3636

37-
private static final int BUNDLE_IDX = 0;
38-
private static final int STARTLEVEL_IDX = 1;
39-
4037
private final Felix m_felix;
4138
private final ServiceRegistry m_registry;
42-
private final List m_requests = new ArrayList();
43-
private final List<FrameworkListener[]> m_requestListeners
44-
= new ArrayList<FrameworkListener[]>();
39+
private final List<StartLevelRequest> m_requests = new ArrayList<>();
4540
private ServiceRegistration<StartLevel> m_slReg;
4641
private Thread m_thread = null;
4742

@@ -131,8 +126,7 @@ public void setStartLevel(int startlevel, FrameworkListener... listeners)
131126
throw new IllegalStateException("No inital startlevel yet");
132127
}
133128
// Queue request.
134-
m_requestListeners.add(listeners);
135-
m_requests.add(new Integer(startlevel));
129+
m_requests.add(new StartLevelRequest(null, startlevel, listeners));
136130
m_requests.notifyAll();
137131
}
138132
}
@@ -145,15 +139,14 @@ public void setStartLevel(int startlevel, FrameworkListener... listeners)
145139
**/
146140
/* package */ void setStartLevelAndWait(int startlevel)
147141
{
148-
Object request = new Integer(startlevel);
142+
StartLevelRequest request = new StartLevelRequest(null, startlevel);
149143
synchronized (request)
150144
{
151145
synchronized (m_requests)
152146
{
153147
// Start thread if necessary.
154148
startThread();
155149
// Queue request.
156-
m_requestListeners.add(null);
157150
m_requests.add(request);
158151
m_requests.notifyAll();
159152
}
@@ -241,8 +234,7 @@ else if (startlevel <= 0)
241234
// Synchronously persists the start level.
242235
m_bundle.setStartLevel(startlevel);
243236
// Queue request.
244-
m_requestListeners.add(null);
245-
m_requests.add(new Object[] { m_bundle, new Integer(startlevel) });
237+
m_requests.add(new StartLevelRequest(m_bundle, startlevel));
246238
m_requests.notifyAll();
247239
}
248240
}
@@ -262,11 +254,10 @@ public void run()
262254
{
263255
// This thread loops forever, thus it should
264256
// be a daemon thread.
265-
Object previousRequest = null;
257+
StartLevelRequest previousRequest = null;
266258
while (true)
267259
{
268-
Object request = null;
269-
FrameworkListener[] listeners = null;
260+
StartLevelRequest request = null;
270261
synchronized (m_requests)
271262
{
272263
// Wait for a request.
@@ -290,22 +281,20 @@ public void run()
290281

291282
// Get the requested start level.
292283
request = m_requests.remove(0);
293-
listeners = m_requestListeners.remove(0);
294284
}
295285

296-
// If the request object is an Integer, then the request
297-
// is to set the framework start level. If the request is
298-
// an Object array, then the request is to set the start
299-
// level for a bundle.
286+
// If the request object has no bundle, then the request
287+
// is to set the framework start level, otherwise the
288+
// request is to set the start level for a bundle.
300289
// NOTE: We don't catch any exceptions here, because
301290
// the invoked methods shield us from exceptions by
302291
// catching Throwables when they invoke callbacks.
303-
if (request instanceof Integer)
292+
if (request.getBundle() == null)
304293
{
305294
// Set the new framework start level.
306295
try
307296
{
308-
m_felix.setActiveStartLevel(((Integer) request).intValue(), listeners);
297+
m_felix.setActiveStartLevel(request.getStartLevel(), request.getListeners());
309298
}
310299
catch (IllegalStateException ise)
311300
{
@@ -333,9 +322,7 @@ public void run()
333322
}
334323
else
335324
{
336-
Bundle bundle = (Bundle) ((Object[]) request)[BUNDLE_IDX];
337-
int startlevel = ((Integer) ((Object[]) request)[STARTLEVEL_IDX]).intValue();
338-
m_felix.setBundleStartLevel(bundle, startlevel);
325+
m_felix.setBundleStartLevel(request.getBundle(), request.getStartLevel());
339326
}
340327

341328
// Notify any waiting thread that this request is done.
@@ -345,4 +332,37 @@ public void run()
345332
}
346333
}
347334
}
348-
}
335+
336+
/**
337+
* This class holds a start level request. If the bundle is null then the
338+
* request is to set the framework start level.
339+
*/
340+
private static final class StartLevelRequest
341+
{
342+
private final Bundle m_bundle;
343+
private final int m_startLevel;
344+
private final FrameworkListener[] m_listeners;
345+
346+
private StartLevelRequest(Bundle bundle, int startLevel, FrameworkListener... listeners)
347+
{
348+
m_bundle = bundle;
349+
m_startLevel = startLevel;
350+
m_listeners = listeners;
351+
}
352+
353+
private Bundle getBundle()
354+
{
355+
return m_bundle;
356+
}
357+
358+
private int getStartLevel()
359+
{
360+
return m_startLevel;
361+
}
362+
363+
public FrameworkListener[] getListeners()
364+
{
365+
return m_listeners;
366+
}
367+
}
368+
}

0 commit comments

Comments
 (0)