Skip to content

Commit

Permalink
fix msgpack deserialization... why?
Browse files Browse the repository at this point in the history
  • Loading branch information
Yatao Li committed Nov 19, 2020
1 parent fe46347 commit ee9fcf9
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 18 deletions.
9 changes: 3 additions & 6 deletions Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,10 @@ type MsgPackFormatter(resolver: IFormatterResolver) =
member x.Deserialize(bytes: byte[] , offset: int, formatterResolver: IFormatterResolver , readSize: byref<int>) =
if MessagePackBinary.GetMessagePackType(bytes, offset) = MessagePackType.Extension then
let result = MessagePackBinary.ReadExtensionFormat(bytes, offset, &readSize)
if result.TypeCode = 1y then
let mutable _size = 0
m_formatter.Deserialize(result.Data, 0, formatterResolver, &_size)
else
m_formatter.Deserialize(bytes, offset, formatterResolver, &readSize)
let mutable _size = 0
m_formatter.Deserialize(result.Data, 0, formatterResolver, &_size)
else
m_formatter.Deserialize(bytes, offset, formatterResolver, &readSize)
m_formatter.Deserialize(bytes, offset, formatterResolver, &readSize)

type MsgPackResolver() =
static let s_formatter = box(MsgPackFormatter(MessagePack.Resolvers.StandardResolver.Instance))
Expand Down
3 changes: 1 addition & 2 deletions Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"profiles": {
"fvim": {
"commandName": "Project",
"commandLineArgs": "--daemon"
"commandName": "Project"
},
"norc": {
"commandName": "Project",
Expand Down
2 changes: 1 addition & 1 deletion common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ let newProcess prog args stderrenc =
p.EnableRaisingEvents <- true
// in case the parent crashed and we happen to be running Windows(tm)...
// TODO need further investigation.
ignore <| AppDomain.CurrentDomain.ProcessExit.Subscribe(fun _ -> p.Kill(true))
ignore <| AppDomain.CurrentDomain.ProcessExit.Subscribe(fun _ -> try p.Kill(true) with _ -> ())
p

[<AutoOpen>]
Expand Down
6 changes: 5 additions & 1 deletion model.fs
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ let Start (serveropts, norc, debugMultigrid) =
trace "commencing early initialization..."

async {
do! Async.SwitchToNewThread()

let! api_info = Async.AwaitTask(nvim.call { method = "nvim_get_api_info"; parameters = [||] })
let api_query_result =
match api_info.result with
Expand Down Expand Up @@ -663,7 +665,9 @@ let Start (serveropts, norc, debugMultigrid) =
if not norc then
let! _ = Async.AwaitTask(nvim.command "if v:vim_did_enter | runtime! ginit.vim | else | execute \"autocmd VimEnter * runtime! ginit.vim\" | endif")
()
} |> Async.RunSynchronously
}
|> Async.Start
|> ignore

let Flush =
ev_flush.Publish
Expand Down
23 changes: 15 additions & 8 deletions neovim.fs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ type Nvim() =
if id < 0 then
proc.Kill()
failwithf "Remote daemon closed the connection with error code %d" id
else
trace "Connected to session %d" id
TunneledSession proc

member this.start opts =
Expand Down Expand Up @@ -129,28 +131,33 @@ type Nvim() =
let read (ob: IObserver<obj>) (cancel: CancellationToken) =
Task.Factory.StartNew(fun () ->
trace "begin read loop"
let mutable ex = false
while not ex && not cancel.IsCancellationRequested do
let mutable channelClosed = false
let mutable unhandledException = None
while not channelClosed && not cancel.IsCancellationRequested && unhandledException.IsNone do
try
let data = MessagePackSerializer.Deserialize<obj>(stdout, true)
ob.OnNext(data)
with
| :? InvalidOperationException
| :? InvalidOperationException as _ex when _ex.Message = "Invalid MessagePack code was detected, code:-1"
-> channelClosed <- true
| :? System.IO.IOException
| :? System.Net.Sockets.SocketException
| :? ObjectDisposedException
as _ex -> ex <- true
-> channelClosed <- true
| ex -> unhandledException <- Some ex

let ec = serverExitCode()
if ec.IsSome then
let code = ec.Value
match serverExitCode(), unhandledException with
| Some code, _ ->
trace "end read loop: process exited, code = %d" code
if code <> 0 then
m_cancelSrc.Cancel()
ob.OnNext([|box (Crash code)|])
else
ob.OnNext([|box Exit|])
else
| _, Some ex ->
trace "end read loop: unhandled exception."
ob.OnNext([|box (UnhandledException ex)|])
| _ ->
trace "end read loop."
ob.OnNext([|box Exit|])
ob.OnCompleted()
Expand Down
3 changes: 3 additions & 0 deletions states.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Event =
| Notification of nreq: Request
| Error of emsg: string
| Crash of ccode: int32
| UnhandledException of ex: exn
| Exit

let private _stateChangeEvent = Event<string>()
Expand Down Expand Up @@ -278,6 +279,8 @@ let msg_dispatch =
trace "rpc" "neovim crashed with code %d" code
_crashcode <- code
failwithf "neovim crashed"
| UnhandledException ex ->
raise ex
| other ->
trace "rpc" "unrecognized event: %A" other

Expand Down

0 comments on commit ee9fcf9

Please sign in to comment.