Beispiel #1
0
status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {
    String8 ashmemName("CursorWindow: ");
    ashmemName.append(name);

    status_t result;
    int ashmemFd = ashmem_create_region(ashmemName.string(), size);
    if (ashmemFd < 0) {
    	ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, ashmem_create_region return errno = %d",errno);
        result = -errno;
    } else {
        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
        if (result >= 0) {
            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
            if (data == MAP_FAILED) {
            	ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, mmap return errno = %d",errno);
                result = -errno;
            } else {
                result = ashmem_set_prot_region(ashmemFd, PROT_READ);
                if (result >= 0) {
                    CursorWindow* window = new CursorWindow(name, ashmemFd,
                            data, size, false /*readOnly*/);
                    result = window->clear();
                    if (!result) {
                        LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "
                                "numRows=%d, numColumns=%d, mSize=%d, mData=%p",
                                window->mHeader->freeOffset,
                                window->mHeader->numRows,
                                window->mHeader->numColumns,
                                window->mSize, window->mData);
                        *outCursorWindow = window;
                        return OK;
                    }
                    ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, window->clear return errno = %d",errno);
                    delete window;
                } else {
                    ALOG(LOG_ERROR,LOG_TAG,"CursorWindow::create, ashmeme_set_prot_region return errno = %d",errno);	
                }
            }
            ::munmap(data, size);
        }
        ::close(ashmemFd);
    }
    *outCursorWindow = NULL;
    return result;
}
status_t InputChannel::openInputChannelPair(const String8& name,
        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
    status_t result;

    String8 ashmemName("InputChannel ");
    ashmemName.append(name);
    int serverAshmemFd = ashmem_create_region(ashmemName.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
    if (serverAshmemFd < 0) {
        result = -errno;
        ALOGE("channel '%s' ~ Could not create shared memory region. errno=%d",
                name.string(), errno);
    } else {
        result = ashmem_set_prot_region(serverAshmemFd, PROT_READ | PROT_WRITE);
        if (result < 0) {
            ALOGE("channel '%s' ~ Error %d trying to set protection of ashmem fd %d.",
                    name.string(), result, serverAshmemFd);
        } else {
            // Dup the file descriptor because the server and client input channel objects that
            // are returned may have different lifetimes but they share the same shared memory region.
            int clientAshmemFd;
            clientAshmemFd = dup(serverAshmemFd);
            if (clientAshmemFd < 0) {
                result = -errno;
                ALOGE("channel '%s' ~ Could not dup() shared memory region fd. errno=%d",
                        name.string(), errno);
            } else {
                int forward[2];
                if (pipe(forward)) {
                    result = -errno;
                    ALOGE("channel '%s' ~ Could not create forward pipe.  errno=%d",
                            name.string(), errno);
                } else {
                    int reverse[2];
                    if (pipe(reverse)) {
                        result = -errno;
                        ALOGE("channel '%s' ~ Could not create reverse pipe.  errno=%d",
                                name.string(), errno);
                    } else {
                        String8 serverChannelName = name;
                        serverChannelName.append(" (server)");
                        outServerChannel = new InputChannel(serverChannelName,
                                serverAshmemFd, reverse[0], forward[1]);

                        String8 clientChannelName = name;
                        clientChannelName.append(" (client)");
                        outClientChannel = new InputChannel(clientChannelName,
                                clientAshmemFd, forward[0], reverse[1]);
                        return OK;
                    }
                    ::close(forward[0]);
                    ::close(forward[1]);
                }
                ::close(clientAshmemFd);
            }
        }
        ::close(serverAshmemFd);
    }

    outServerChannel.clear();
    outClientChannel.clear();
    return result;
}