protected void notifyBackground() { if (Thread.currentThread() != backgroundThread) { synchronized (backgroundThread) { backgroundThread.notifyAll(); } } }
// NOTE: Implement any IChildProcessService methods here. @Override public int setupConnection(Bundle args, IChildProcessCallback callback) { mCallback = callback; // Required to unparcel FileDescriptorInfo. args.setClassLoader(getClassLoader()); synchronized (mMainThread) { // Allow the command line to be set via bind() intent or setupConnection, but // the FD can only be transferred here. if (mCommandLineParams == null) { mCommandLineParams = args.getStringArray(ChildProcessConnection.EXTRA_COMMAND_LINE); } // We must have received the command line by now assert mCommandLineParams != null; mCpuCount = args.getInt(ChildProcessConnection.EXTRA_CPU_COUNT); mCpuFeatures = args.getLong(ChildProcessConnection.EXTRA_CPU_FEATURES); assert mCpuCount > 0; Parcelable[] fdInfosAsParcelable = args.getParcelableArray(ChildProcessConnection.EXTRA_FILES); // For why this arraycopy is necessary: // http://stackoverflow.com/questions/8745893/i-dont-get-why-this-classcastexception-occurs mFdInfos = new FileDescriptorInfo[fdInfosAsParcelable.length]; System.arraycopy(fdInfosAsParcelable, 0, mFdInfos, 0, fdInfosAsParcelable.length); Bundle sharedRelros = args.getBundle(Linker.EXTRA_LINKER_SHARED_RELROS); if (sharedRelros != null) { Linker.getInstance().useSharedRelros(sharedRelros); sharedRelros = null; } mMainThread.notifyAll(); } return Process.myPid(); }
/** Processes splash screen touch events */ @Override public boolean onTouchEvent(MotionEvent evt) { if (evt.getAction() == MotionEvent.ACTION_DOWN) { synchronized (mSplashThread) { mSplashThread.notifyAll(); } } return true; }
@Override public IBinder onBind(Intent intent) { // We call stopSelf() to request that this service be stopped as soon as the client // unbinds. Otherwise the system may keep it around and available for a reconnect. The // child processes do not currently support reconnect; they must be initialized from // scratch every time. stopSelf(); synchronized (mMainThread) { mCommandLineParams = intent.getStringArrayExtra(ChildProcessConnection.EXTRA_COMMAND_LINE); // mLinkerParams is never used if Linker.isUsed() returns false. // See onCreate(). mLinkerParams = new ChromiumLinkerParams(intent); mIsBound = true; mMainThread.notifyAll(); } return mBinder; }
@Override public void handle(TaskSchedulerEvent event) { if (event.getType() == EventType.T_SCHEDULE) { if (event instanceof FragmentScheduleEvent) { FragmentScheduleEvent castEvent = (FragmentScheduleEvent) event; if (context.isLeafQuery()) { TaskAttemptScheduleContext taskContext = new TaskAttemptScheduleContext(); Task task = Stage.newEmptyTask(context, taskContext, stage, nextTaskId++); task.addFragment(castEvent.getLeftFragment(), true); scheduledObjectNum++; if (castEvent.hasRightFragments()) { task.addFragments(castEvent.getRightFragments()); } stage.getEventHandler().handle(new TaskEvent(task.getId(), TaskEventType.T_SCHEDULE)); } else { fragmentsForNonLeafTask = new FileFragment[2]; fragmentsForNonLeafTask[0] = castEvent.getLeftFragment(); if (castEvent.hasRightFragments()) { Collection<Fragment> var = castEvent.getRightFragments(); FileFragment[] rightFragments = var.toArray(new FileFragment[var.size()]); fragmentsForNonLeafTask[1] = rightFragments[0]; if (rightFragments.length > 1) { broadcastFragmentsForNonLeafTask = new FileFragment[rightFragments.length - 1]; System.arraycopy( rightFragments, 1, broadcastFragmentsForNonLeafTask, 0, broadcastFragmentsForNonLeafTask.length); } else { broadcastFragmentsForNonLeafTask = null; } } } } else if (event instanceof FetchScheduleEvent) { FetchScheduleEvent castEvent = (FetchScheduleEvent) event; Map<String, List<FetchImpl>> fetches = castEvent.getFetches(); TaskAttemptScheduleContext taskScheduleContext = new TaskAttemptScheduleContext(); Task task = Stage.newEmptyTask(context, taskScheduleContext, stage, nextTaskId++); scheduledObjectNum++; for (Entry<String, List<FetchImpl>> eachFetch : fetches.entrySet()) { task.addFetches(eachFetch.getKey(), eachFetch.getValue()); task.addFragment(fragmentsForNonLeafTask[0], true); if (fragmentsForNonLeafTask[1] != null) { task.addFragment(fragmentsForNonLeafTask[1], true); } } if (broadcastFragmentsForNonLeafTask != null && broadcastFragmentsForNonLeafTask.length > 0) { task.addFragments(Arrays.asList(broadcastFragmentsForNonLeafTask)); } stage.getEventHandler().handle(new TaskEvent(task.getId(), TaskEventType.T_SCHEDULE)); } else if (event instanceof TaskAttemptToSchedulerEvent) { TaskAttemptToSchedulerEvent castEvent = (TaskAttemptToSchedulerEvent) event; if (context.isLeafQuery()) { scheduledRequests.addLeafTask(castEvent); } else { scheduledRequests.addNonLeafTask(castEvent); } if (needWakeup.getAndSet(false)) { // wake up scheduler thread after scheduled synchronized (schedulingThread) { schedulingThread.notifyAll(); } } } } else if (event.getType() == EventType.T_SCHEDULE_CANCEL) { // when a stage is killed, unassigned query unit attmpts are canceled from the scheduler. // This event is triggered by TaskAttempt. TaskAttemptToSchedulerEvent castedEvent = (TaskAttemptToSchedulerEvent) event; scheduledRequests.leafTasks.remove(castedEvent.getTaskAttempt().getId()); LOG.info( castedEvent.getTaskAttempt().getId() + " is canceled from " + this.getClass().getSimpleName()); ((TaskAttemptToSchedulerEvent) event) .getTaskAttempt() .handle( new TaskAttemptEvent( castedEvent.getTaskAttempt().getId(), TaskAttemptEventType.TA_SCHEDULE_CANCELED)); } }