NativeDaemonConnector: offload callbacks to another thread.
Now callbacks can communicate to the same daemon without causing a deadlock. This also improves the latency of calls because they no longer need to wait for the callbacks for the pending events. Change-Id: I153fcf16bd64de79ee1c1a57d3cfdb12b354cf47
This commit is contained in:
@@ -19,6 +19,9 @@ package com.android.server;
|
|||||||
import android.net.LocalSocketAddress;
|
import android.net.LocalSocketAddress;
|
||||||
import android.net.LocalSocket;
|
import android.net.LocalSocket;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.HandlerThread;
|
||||||
|
import android.os.Message;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -39,7 +42,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||||||
* daemon which uses the libsysutils FrameworkListener
|
* daemon which uses the libsysutils FrameworkListener
|
||||||
* protocol.
|
* protocol.
|
||||||
*/
|
*/
|
||||||
final class NativeDaemonConnector implements Runnable {
|
final class NativeDaemonConnector implements Runnable, Handler.Callback {
|
||||||
private static final boolean LOCAL_LOGD = false;
|
private static final boolean LOCAL_LOGD = false;
|
||||||
|
|
||||||
private BlockingQueue<String> mResponseQueue;
|
private BlockingQueue<String> mResponseQueue;
|
||||||
@@ -47,6 +50,7 @@ final class NativeDaemonConnector implements Runnable {
|
|||||||
private String TAG = "NativeDaemonConnector";
|
private String TAG = "NativeDaemonConnector";
|
||||||
private String mSocket;
|
private String mSocket;
|
||||||
private INativeDaemonConnectorCallbacks mCallbacks;
|
private INativeDaemonConnectorCallbacks mCallbacks;
|
||||||
|
private Handler mCallbackHandler;
|
||||||
|
|
||||||
private final int BUFFER_SIZE = 4096;
|
private final int BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
@@ -76,7 +80,11 @@ final class NativeDaemonConnector implements Runnable {
|
|||||||
mResponseQueue = new LinkedBlockingQueue<String>(responseQueueSize);
|
mResponseQueue = new LinkedBlockingQueue<String>(responseQueueSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
|
||||||
|
thread.start();
|
||||||
|
mCallbackHandler = new Handler(thread.getLooper(), this);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
@@ -88,6 +96,21 @@ final class NativeDaemonConnector implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessage(Message msg) {
|
||||||
|
String event = (String) msg.obj;
|
||||||
|
try {
|
||||||
|
if (!mCallbacks.onEvent(msg.what, event, event.split(" "))) {
|
||||||
|
Slog.w(TAG, String.format(
|
||||||
|
"Unhandled event '%s'", event));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Slog.e(TAG, String.format(
|
||||||
|
"Error handling '%s'", event), e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void listenToSocket() throws IOException {
|
private void listenToSocket() throws IOException {
|
||||||
LocalSocket socket = null;
|
LocalSocket socket = null;
|
||||||
|
|
||||||
@@ -119,20 +142,13 @@ final class NativeDaemonConnector implements Runnable {
|
|||||||
String event = new String(buffer, start, i - start);
|
String event = new String(buffer, start, i - start);
|
||||||
if (LOCAL_LOGD) Slog.d(TAG, String.format("RCV <- {%s}", event));
|
if (LOCAL_LOGD) Slog.d(TAG, String.format("RCV <- {%s}", event));
|
||||||
|
|
||||||
String[] tokens = event.split(" ");
|
String[] tokens = event.split(" ", 2);
|
||||||
try {
|
try {
|
||||||
int code = Integer.parseInt(tokens[0]);
|
int code = Integer.parseInt(tokens[0]);
|
||||||
|
|
||||||
if (code >= ResponseCode.UnsolicitedInformational) {
|
if (code >= ResponseCode.UnsolicitedInformational) {
|
||||||
try {
|
mCallbackHandler.sendMessage(
|
||||||
if (!mCallbacks.onEvent(code, event, tokens)) {
|
mCallbackHandler.obtainMessage(code, event));
|
||||||
Slog.w(TAG, String.format(
|
|
||||||
"Unhandled event (%s)", event));
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Slog.e(TAG, String.format(
|
|
||||||
"Error handling '%s'", event), ex);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
mResponseQueue.put(event);
|
mResponseQueue.put(event);
|
||||||
|
|||||||
Reference in New Issue
Block a user