 Return t when server is ready.  Signal error in case of timeout.
 The timeout can be set with the variable
 `ycmd-startup-timeout'."
-  (let ((server-start-time (float-time))
-        server-started)
-    (while (and (not server-started) (ycmd-running?))
-      (sit-for 0.1)
-      (if (ycmd--server-ready? :include-subserver)
-          (progn
+  (catch 'ready
+    (let ((server-start-time (float-time)))
+      (setq ycmd--server-actual-port nil)
+      (while (ycmd-running?)
+        (if (and (or ycmd--server-actual-port
+                     (ycmd--parse-server-port))
+                 (progn
+                   (sit-for 0.1)
+                   (ycmd--server-ready? :include-subserver)))
+            (progn
+              (ycmd--with-all-ycmd-buffers
+                (ycmd--report-status 'unparsed))
+              (throw 'ready t))
+          ;; timeout after specified period
+          (when (< ycmd-startup-timeout
+                   (- (float-time) server-start-time))
+            (ycmd-close)
             (ycmd--with-all-ycmd-buffers
-              (ycmd--report-status 'unparsed))
-            (setq server-started t))
-        ;; timeout after specified period
-        (when (< ycmd-startup-timeout
-                 (- (float-time) server-start-time))
-          (ycmd-close)
-          (ycmd--with-all-ycmd-buffers
-            (ycmd--report-status 'errored))
-          (error "ERROR: Ycmd server timeout"))))
-    server-started))
+              (ycmd--report-status 'errored))
+            (error "ERROR: Ycmd server timeout")))))))
 
 (defun ycmd--column-in-bytes ()
   "Calculate column offset in bytes for the current position and buffer."

    (with-current-buffer proc-buff
      (buffer-disable-undo)
      (erase-buffer))
    (let* ((port (or (and (numberp ycmd-server-port)
                          (> ycmd-server-port 0)
                          ycmd-server-port)
                     (ycmd--get-unused-port)))
           (hmac-secret (ycmd--generate-hmac-secret))
           (options-file (ycmd--create-options-file hmac-secret))
           (args (apply 'list (format "--port=%d" port)
                        (concat "--options_file=" options-file)
                        ycmd-server-args))
           (server-program+args (append ycmd-server-command args))
           (proc (apply #'start-process ycmd--server-process-name proc-buff
                        server-program+args)))
      (set-process-query-on-exit-flag proc nil)
      (set-process-sentinel proc #'ycmd--server-process-sentinel)
      (setq ycmd--server-actual-port port)
      (setq ycmd--hmac-secret hmac-secret)
      proc)))

(defun ycmd--wait-until-server-ready ()
  "Wait until server is ready.

      (insert (ycmd--json-encode options)))
    options-file))

(defun ycmd--exit-code-as-string (code)
  "Return exit status message for CODE."
  (pcase code
