예제 #1
0
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);
        }
      }

    }
  }
}
예제 #2
0
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);
  } 
}
예제 #3
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;
}
예제 #4
0
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;
            }
        }
예제 #5
0
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);
    }
}
예제 #6
0
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;
    }        
  }
}
예제 #7
0
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;
  }
}
예제 #8
0
파일: async_io.c 프로젝트: mlang/brltty
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);
}