/** * Execute the task. * * @return true if it works, false otherwise. */ @Override public Boolean call() { final long start = System.nanoTime(); CompletionStatus result = CompletionStatus.FAILED; try { Log.d(LOG_TAG, "Download Task started for download id = " + downloadId); failureMessage = MSG_OKAY; downloadErrorCode = DownloadError.NO_ERROR.getValue(); if (!ensureFolderExists(destination)) { finish( CompletionStatus.FAILED, failureMessage, cumulativeBytesRead, totalBytes, autoRestart, downloadErrorCode); return false; } if (null != downloadTag && 0L < downloadOffset) { if (!ensurePartialFilePresent(destination, downloadOffset)) { // if we don't have the partial file any more, we have to start again downloadOffset = 0L; } } result = readFromUri(destination); finish( result, failureMessage, cumulativeBytesRead, totalBytes, autoRestart, downloadErrorCode); return CompletionStatus.SUCCEEDED == result; } finally { // Make sure we release wifi lock (if any) networkStatusProvider.releaseWifiLock(downloadId); final long duration = System.nanoTime() - start; Log.d( LOG_TAG, String.format( "Download result(%s) for download task with uri(%s) took %.3f seconds.", result.name(), uri, (double) duration / 1000000000)); } }
/** Poller main loop */ @Override public void run() { for (; ; ) { CompletionStatus info; try { info = GetQueuedCompletionStatus(port); } catch (WindowsException x) { // this should not happen x.printStackTrace(); return; } // wakeup if (info.completionKey() == WAKEUP_COMPLETION_KEY) { boolean shutdown = processRequests(); if (shutdown) { return; } continue; } // map completionKey to get WatchKey WindowsWatchKey key = ck2key.get((int) info.completionKey()); if (key == null) { // We get here when a registration is changed. In that case // the directory is closed which causes an event with the // old completion key. continue; } boolean criticalError = false; int errorCode = info.error(); int messageSize = info.bytesTransferred(); if (errorCode == ERROR_NOTIFY_ENUM_DIR) { // buffer overflow key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); } else if (errorCode != 0 && errorCode != ERROR_MORE_DATA) { // ReadDirectoryChangesW failed criticalError = true; } else { // ERROR_MORE_DATA is a warning about incomplete // data transfer over TCP/UDP stack. For the case // [messageSize] is zero in the most of cases. if (messageSize > 0) { // process non-empty events. processEvents(key, messageSize); } else if (errorCode == 0) { // insufficient buffer size // not described, but can happen. key.signalEvent(StandardWatchEventKinds.OVERFLOW, null); } // start read for next batch of changes try { ReadDirectoryChangesW( key.handle(), key.buffer().address(), CHANGES_BUFFER_SIZE, key.watchSubtree(), ALL_FILE_NOTIFY_EVENTS, key.countAddress(), key.overlappedAddress()); } catch (WindowsException x) { // no choice but to cancel key criticalError = true; } } if (criticalError) { implCancelKey(key); key.signal(); } } }