void kqueueNextFinishedOperation(asyncBase *base) { kqueueBase *localBase = (kqueueBase*)base; pipeMsg msg; int kq, nev, n, i; int eventsNum; opDequeTy *dequeptr; struct kevent *evlist = new struct kevent[MAX_EVENTS]; asyncOp *op; while (true) { eventsNum = localBase->keVector.size(); nev = kevent(localBase->kqueueFd, localBase->keVector.data(), eventsNum, evlist, MAX_EVENTS, 0 ); localBase->keVector.clear(); if (nev == -1) fprintf(stderr, "kevent error: %s", strerror(errno)); if (nev == 0) { fprintf(stderr, "kevent error: no events"); return; } for (n = 0; n < nev; n++) { if (evlist[n].filter == EVFILT_READ) { if (evlist[n].ident == localBase->pipeFd[Read]) { for (i = 0; i < evlist[n].data / sizeof(pipeMsg); i++) { read(localBase->pipeFd[Read], &msg, sizeof(pipeMsg)); op = (asyncOp*)msg.data; switch (msg.cmd) { case Reset : return; break; case UserEventActivate : finishOperation(op, aosSuccess, op->counter == 0); break; } } } else { dequeptr = &(localBase->fdMap[evlist[n].ident].readOps); processReadyFd(dequeptr, &evlist[n], 1); } } else if (evlist[n].filter == EVFILT_WRITE) { dequeptr = &(localBase->fdMap[evlist[n].ident].writeOps); processReadyFd(dequeptr, &evlist[n], 0); } else if (evlist[n].filter == EVFILT_TIMER) { op = (asyncOp*)evlist[n].udata; if (op->info.object->type == ioObjectUserEvent) finishOperation(op, aosSuccess, op->counter == 0); else { finishOperation(op, aosTimeout, 1); } } } } }
void selectNextFinishedOperation(asyncBase *base) { selectBase *localBase = (selectBase*)base; while (1) { int nfds; int result; fd_set readFds; fd_set writeFds; FD_ZERO(&readFds); FD_ZERO(&writeFds); FD_SET(localBase->pipeFd[0], &readFds); nfds = localBase->pipeFd[0] + 1; for (OpLinksMap::iterator I = localBase->readOps.begin(), IE = localBase->readOps.end(); I != IE; ++I) { if (I->second->head) { nfds = std::max(nfds, I->first+1); FD_SET(I->first, &readFds); } } for (OpLinksMap::iterator I = localBase->writeOps.begin(), IE = localBase->writeOps.end(); I != IE; ++I) { asyncOp *op = I->second->head; if (op) { nfds = std::max(nfds, I->first+1); if (op->info.object->type == ioObjectSocket) FD_SET(I->first, &readFds); FD_SET(I->first, &writeFds); } } do { result = select(nfds, &readFds, &writeFds, NULL, NULL); } while (result <= 0 && errno == EINTR); if (FD_ISSET(localBase->pipeFd[0], &readFds)) { int available; ioctl(localBase->pipeFd[0], FIONREAD, &available); asyncOp *op; for (int i = 0; i < available/sizeof(op); i++) { read(localBase->pipeFd[0], &op, sizeof(op)); if (!op) return; if (op) { if (op->info.object->type == ioObjectUserEvent) finishOperation(op, aosSuccess, op->counter == 0); else finishOperation(op, aosTimeout, 0); } } } processReadyFds(localBase, localBase->readOps, &readFds, 1); processReadyFds(localBase, localBase->writeOps, &writeFds, 0); } }
bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name, const AuthorizationSet& input_parameters, const std::string& input_data, const std::string& signature_to_verify, AuthorizationSet* output_parameters, std::string* output_data) { uint64_t handle; auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle); if (!result.isOk()) { ALOGE("BeginOperation failed: %d", int32_t(result)); return false; } AuthorizationSet empty_params; size_t num_input_bytes_consumed; AuthorizationSet ignored_params; result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed, &ignored_params, output_data); if (!result.isOk()) { ALOGE("UpdateOperation failed: %d", int32_t(result)); return false; } result = finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data); if (!result.isOk()) { ALOGE("FinishOperation failed: %d", int32_t(result)); return false; } return true; }
bool MainWindow::QuerySaveDatabase() { if (QuerySaveGame()) { if (m_currentDatabase && qobject_cast<MemoryDatabase*>(database())) { if (database()->isModified()) { int result = MessageDialog::yesNoCancel(tr("The current database is modified!") + '\n' + tr("Save it?")); if (MessageDialog::Yes == result) { startOperation(tr("Saving %1...").arg(database()->name())); Output output(Output::Sgn); connect(&output, SIGNAL(progress(int)), SLOT(slotOperationProgress(int))); output.output(database()->filename(), *database()); finishOperation(tr("%1 saved").arg(database()->name())); return true; } return result != MessageDialog::Cancel; } }
status_t BnAppOpsService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { //printf("AppOpsService received: "); data.print(); switch(code) { case CHECK_OPERATION_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); int32_t res = checkOperation(code, uid, packageName); reply->writeNoException(); reply->writeInt32(res); return NO_ERROR; } break; case NOTE_OPERATION_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); int32_t res = noteOperation(code, uid, packageName); reply->writeNoException(); reply->writeInt32(res); return NO_ERROR; } break; case START_OPERATION_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); sp<IBinder> token = data.readStrongBinder(); int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); int32_t res = startOperation(token, code, uid, packageName); reply->writeNoException(); reply->writeInt32(res); return NO_ERROR; } break; case FINISH_OPERATION_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); sp<IBinder> token = data.readStrongBinder(); int32_t code = data.readInt32(); int32_t uid = data.readInt32(); String16 packageName = data.readString16(); finishOperation(token, code, uid, packageName); reply->writeNoException(); return NO_ERROR; } break; case START_WATCHING_MODE_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); int32_t op = data.readInt32(); String16 packageName = data.readString16(); sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder()); startWatchingMode(op, packageName, callback); reply->writeNoException(); return NO_ERROR; } break; case STOP_WATCHING_MODE_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); sp<IAppOpsCallback> callback = interface_cast<IAppOpsCallback>(data.readStrongBinder()); stopWatchingMode(callback); reply->writeNoException(); return NO_ERROR; } break; case GET_TOKEN_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); sp<IBinder> clientToken = data.readStrongBinder(); sp<IBinder> token = getToken(clientToken); reply->writeNoException(); reply->writeStrongBinder(token); return NO_ERROR; } break; case PERMISSION_TO_OP_CODE_TRANSACTION: { CHECK_INTERFACE(IAppOpsService, data, reply); String16 permission = data.readString16(); const int32_t opCode = permissionToOpCode(permission); reply->writeNoException(); reply->writeInt32(opCode); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }
static void processReadyFds(selectBase *base, OpLinksMap &links, fd_set *fds, int isRead) { for (OpLinksMap::iterator I = links.begin(), IE = links.end(); I != IE; ++I) { int fd = I->first; if (!FD_ISSET(fd, fds)) continue; int available; asyncOpList *list = getFdOperations(links, fd); asyncOp *op = list->head; if (!op) continue; assert(fd == getFd(op) && "Lost asyncop found!"); ioctl(fd, FIONREAD, &available); if (op->info.object->type == ioObjectSocket && available == 0 && isRead) { if (op->info.currentAction != ioAccept) { finishOperation(op, aosDisconnected, 1); continue; } } switch (op->info.currentAction) { case ioConnect : { int error; socklen_t size = sizeof(error); getsockopt(op->info.object->hSocket, SOL_SOCKET, SO_ERROR, &error, &size); finishOperation(op, (error == 0) ? aosSuccess : aosUnknownError, 1); break; } case ioAccept : { struct sockaddr_in clientAddr; socklen_t clientAddrSize = sizeof(clientAddr); op->info.acceptSocket = accept(fd, (sockaddr*)&clientAddr, &clientAddrSize); if (op->info.acceptSocket != -1) { op->info.host.family = 0; op->info.host.ipv4 = clientAddr.sin_addr.s_addr; op->info.host.port = clientAddr.sin_port; finishOperation(op, aosSuccess, 1); } else { finishOperation(op, aosUnknownError, 1); } break; } case ioRead : { int readyForRead = 0; uint8_t *ptr = (uint8_t*)op->info.buffer + op->info.bytesTransferred; readyForRead = std::min(op->info.transactionSize - op->info.bytesTransferred, (size_t)available); read(fd, ptr, readyForRead); op->info.bytesTransferred += readyForRead; if (op->info.bytesTransferred == op->info.transactionSize || !(op->info.flags & afWaitAll)) finishOperation(op, aosSuccess, 1); break; } case ioWrite : { void *buffer = op->useInternalBuffer ? op->internalBuffer : op->info.buffer; uint8_t *ptr = (uint8_t*)buffer + op->info.bytesTransferred; size_t remaining = op->info.transactionSize - op->info.bytesTransferred; ssize_t bytesWritten = write(fd, ptr, remaining); if (bytesWritten == -1) { if (op->info.object->type == ioObjectSocket && errno == EPIPE) { finishOperation(op, aosDisconnected, 1); } else { finishOperation(op, aosUnknownError, 1); } } else { op->info.bytesTransferred += bytesWritten; if (op->info.bytesTransferred == op->info.transactionSize) finishOperation(op, aosSuccess, 1); } break; } case ioReadMsg : { void *ptr = dynamicBufferAlloc(op->info.dynamicArray, available); read(fd, ptr, available); op->info.bytesTransferred += available; finishOperation(op, aosSuccess, 1); break; } case ioWriteMsg : { struct sockaddr_in remoteAddress; void *ptr = op->useInternalBuffer ? op->internalBuffer : op->info.buffer; remoteAddress.sin_family = op->info.host.family; remoteAddress.sin_addr.s_addr = op->info.host.ipv4; remoteAddress.sin_port = op->info.host.port; sendto(fd, ptr, op->info.transactionSize, 0, (sockaddr*)&remoteAddress, sizeof(remoteAddress)); finishOperation(op, aosSuccess, 1); break; } case ioMonitor : { finishOperation(op, aosMonitoring, 0); break; } default : break; } } }
static void processReadyFd(opDequeTy *dequeptr, struct kevent *ev, int isRead) { int available, readyForRead, readyForWrite; asyncOp *op; if (dequeptr->empty()) return; assert(!dequeptr->empty() && "Error: Queue is empty!"); op = dequeptr->front(); if (ev->flags == EV_EOF || ev->data == 0) { if (op->info.object->type == ioObjectSocket || op->info.object->type == ioObjectSocketSyn) finishOperation(op, aosDisconnected, 1); return; } available = ev->data; switch (op->info.currentAction) { case ioConnect : { int error; socklen_t size = sizeof(error); getsockopt(op->info.object->hSocket, SOL_SOCKET, SO_ERROR, &error, &size); finishOperation(op, (error == 0) ? aosSuccess : aosUnknownError, 1); break; } case ioAccept : { struct sockaddr_in clientAddr; socklen_t clientAddrSize = sizeof(clientAddr); op->info.acceptSocket = accept(ev->ident, (struct sockaddr *)&clientAddr, &clientAddrSize); if (op->info.acceptSocket != -1) { op->info.host.family = 0; op->info.host.ipv4 = clientAddr.sin_addr.s_addr; op->info.host.port = clientAddr.sin_port; finishOperation(op, aosSuccess, 1); } else { finishOperation(op, aosUnknownError, 1); } break; } case ioRead : { uint8_t *ptr = (uint8_t *)op->info.buffer + op->info.bytesTransferred; readyForRead = (op->info.transactionSize - op->info.bytesTransferred < (size_t)available) ? op->info.transactionSize - op->info.bytesTransferred : (size_t)available; read(ev->ident, ptr, readyForRead); op->info.bytesTransferred += readyForRead; if (op->info.bytesTransferred == op->info.transactionSize || !(op->info.flags & afWaitAll)) finishOperation(op, aosSuccess, 1); break; } case ioWrite : { uint8_t *ptr = op->useInternalBuffer ? (uint8_t*)op->internalBuffer : (uint8_t*)op->info.buffer; ptr += op->info.bytesTransferred; readyForWrite = (op->info.transactionSize - op->info.bytesTransferred < (size_t)available) ? op->info.transactionSize - op->info.bytesTransferred : (size_t)available; write(ev->ident, ptr, readyForWrite); if (op->info.object->type == ioObjectSocket && errno == EPIPE) finishOperation(op, aosDisconnected, 1); else { op->info.bytesTransferred += readyForWrite; if (op->info.bytesTransferred == op->info.transactionSize || !(op->info.flags & afWaitAll)) finishOperation(op, aosSuccess, 1); } break; } case ioReadMsg : { void *ptr = dynamicBufferAlloc(op->info.dynamicArray, available); read(ev->ident, ptr, available); op->info.bytesTransferred += available; finishOperation(op, aosSuccess, 1); break; } case ioWriteMsg : { struct sockaddr_in remoteAddress; uint8_t *ptr = op->useInternalBuffer ? (uint8_t*)op->internalBuffer : (uint8_t*)op->info.buffer; ptr += op->info.bytesTransferred; remoteAddress.sin_family = op->info.host.family; remoteAddress.sin_addr.s_addr = op->info.host.ipv4; remoteAddress.sin_port = op->info.host.port; sendto(ev->ident, ptr, op->info.transactionSize, 0, (struct sockaddr *)&remoteAddress, sizeof(remoteAddress)); if (op->info.object->type == ioObjectSocket && errno == EPIPE) finishOperation(op, aosDisconnected, 1); else { op->info.bytesTransferred += readyForWrite; if (op->info.bytesTransferred == op->info.transactionSize || !(op->info.flags & afWaitAll)) finishOperation(op, aosSuccess, 1); } break; } case ioMonitor : { finishOperation(op, aosMonitoring, 0); break; } default : break; } }
int asyncExecuteIoCallback (AsyncIoData *iod, long int timeout) { if (iod) { Queue *functions = iod->functionQueue; unsigned int functionCount = functions? getQueueSize(functions): 0; prepareMonitors(); if (functionCount) { MonitorEntry monitorArray[functionCount]; MonitorGroup monitors = { .array = monitorArray, .count = 0 }; int executed = 0; Element *functionElement = processQueue(functions, addFunctionMonitor, &monitors); if (!functionElement) { if (!monitors.count) { approximateDelay(timeout); } else if (awaitMonitors(&monitors, timeout)) { functionElement = processQueue(functions, testFunctionMonitor, NULL); } } if (functionElement) { FunctionEntry *function = getElementItem(functionElement); Element *operationElement = getActiveOperationElement(function); OperationEntry *operation = getElementItem(operationElement); if (!operation->finished) finishOperation(operation); operation->active = 1; if (!function->methods->invokeCallback(operation)) operation->cancel = 1; operation->active = 0; executed = 1; if (operation->cancel) { deleteElement(operationElement); } else { operation->error = 0; } if ((operationElement = getActiveOperationElement(function))) { operation = getElementItem(operationElement); if (!operation->finished) startOperation(operation); requeueElement(functionElement); } else { deleteElement(functionElement); } } return executed; } } approximateDelay(timeout); return 0; } static void deallocateOperationEntry (void *item, void *data) { OperationEntry *operation = item; if (operation->extension) free(operation->extension); free(operation); }