solaris: Fix crash on closing libusb handle

libusb_close() can interrupt transfer to device,
setting dev_handle to NULL.
In this case all async requests should exit gracefully.

Also usbi_signal_transfer_completion() can dereference dev_handle
in this case.

Closes #434

Signed-off-by: Nathan Hjelm <hjelmn@me.com>
diff --git a/libusb/io.c b/libusb/io.c
index 1e9357c..ef2b7c4 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1711,15 +1711,19 @@
  * function will be called the next time an event handler runs. */
 void usbi_signal_transfer_completion(struct usbi_transfer *transfer)
 {
-	struct libusb_context *ctx = ITRANSFER_CTX(transfer);
-	int pending_events;
+	libusb_device_handle *dev_handle = USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->dev_handle;
 
-	usbi_mutex_lock(&ctx->event_data_lock);
-	pending_events = usbi_pending_events(ctx);
-	list_add_tail(&transfer->completed_list, &ctx->completed_transfers);
-	if (!pending_events)
-		usbi_signal_event(ctx);
-	usbi_mutex_unlock(&ctx->event_data_lock);
+	if (dev_handle) {
+		struct libusb_context *ctx = HANDLE_CTX(dev_handle);
+		int pending_events;
+
+		usbi_mutex_lock(&ctx->event_data_lock);
+		pending_events = usbi_pending_events(ctx);
+		list_add_tail(&transfer->completed_list, &ctx->completed_transfers);
+		if (!pending_events)
+			usbi_signal_event(ctx);
+		usbi_mutex_unlock(&ctx->event_data_lock);
+	}
 }
 
 /** \ingroup libusb_poll
diff --git a/libusb/os/sunos_usb.c b/libusb/os/sunos_usb.c
index 05a5ef6..6a3f633 100644
--- a/libusb/os/sunos_usb.c
+++ b/libusb/os/sunos_usb.c
@@ -1196,26 +1196,32 @@
 	int ret;
 	sunos_dev_handle_priv_t *hpriv;
 	uint8_t ep;
+	libusb_device_handle *dev_handle;
 
-	hpriv = (sunos_dev_handle_priv_t *)xfer->dev_handle->os_priv;
-	ep = sunos_usb_ep_index(xfer->endpoint);
+	dev_handle = xfer->dev_handle;
 
-	ret = aio_error(aiocb);
-	if (ret != 0) {
-		xfer->status = sunos_usb_get_status(hpriv->eps[ep].statfd);
-	} else {
-		xfer->actual_length =
-		    LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)->transferred =
-		    aio_return(aiocb);
+	/* libusb can forcibly interrupt transfer in do_close() */
+	if (dev_handle != NULL) {
+		hpriv = (sunos_dev_handle_priv_t *)dev_handle->os_priv;
+		ep = sunos_usb_ep_index(xfer->endpoint);
+
+		ret = aio_error(aiocb);
+		if (ret != 0) {
+			xfer->status = sunos_usb_get_status(hpriv->eps[ep].statfd);
+		} else {
+			xfer->actual_length =
+			    LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)->transferred =
+			    aio_return(aiocb);
+		}
+
+		usb_dump_data(xfer->buffer, xfer->actual_length);
+
+		usbi_dbg("ret=%d, len=%d, actual_len=%d", ret, xfer->length,
+		    xfer->actual_length);
+
+		/* async notification */
+		usbi_signal_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer));
 	}
-
-	usb_dump_data(xfer->buffer, xfer->actual_length);
-
-	usbi_dbg("ret=%d, len=%d, actual_len=%d", ret, xfer->length,
-	    xfer->actual_length);
-
-	/* async notification */
-	usbi_signal_transfer_completion(LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer));
 }
 
 static int
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index aefd792..e38dc22 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11359
+#define LIBUSB_NANO 11360