Example #1
0
        private int HandleWriteRead(Thread current, ref Arch.ExceptionRegisters regs, UserPtr userBwr, binder_write_read bwr)
        {
            var writeBuf = bwr.write_buffer;
            var writeSize = bwr.write_size;
            var buf = Globals.AllocateAlignedCompletionBuffer(MARSHAL_BUF_PAGES * Arch.ArchDefinition.PageSize);
            if (!buf.isValid)
                return -ErrorCode.ENOMEM;

            var marshaler = new BinderIPCMarshaler(current, buf);

            if (bwr.write_consumed != 0)
            {
                Arch.Console.WriteLine("BinderINode::HandleWriteRead: write_consumed != 0");
                Utils.Panic();
            }

            var r = marshaler.Marshal(writeBuf, writeSize);
            if (r < 0)
            {
                Arch.Console.WriteLine("Marshaling error");
                Globals.CompletionQueueAllocator.FreePages(new Pointer(buf.Location), MARSHAL_BUF_PAGES);
                return -1;
            }

            sys_binder_write_desc desc;
            desc.buffer_size = marshaler.WriteCursor;
            desc.bwr_write_size = writeSize;
            desc.write_buffer = new Pointer(buf.Location);
            desc.patch_table_entries = marshaler.CurrentPatchEntry;
            desc.patch_table_offset = marshaler.PatchTableOffset;
            desc.read_consumed = 0;
            desc.write_consumed = 0;

            var binder_cp = new BinderCompletion(current, userBwr, desc, buf);

            r = Arch.IPCStubs.linux_sys_binder_write_read_async(current.Parent.helperPid, current.impl._value.thread._value, desc);

            if (r < 0)
            {
                binder_cp.Dispose();
                return r;
            }

            Globals.CompletionQueue.Enqueue(binder_cp);
            current.SaveState(ref regs);
            current.AsyncReturn = true;
            return 0;
        }