Add support for sqlite3_unlock_notify
diff --git a/callback.c b/callback.c
new file mode 100644
index 0000000..95b7ecb
--- /dev/null
+++ b/callback.c
@@ -0,0 +1,5 @@
+void _unlock_notify_callback(void *arg, int argc)
+{
+  extern void unlock_notify_callback(void *, int);
+  unlock_notify_callback(arg, argc);
+}
diff --git a/callback.go b/callback.go
index 29ece3d..e9d614c 100644
--- a/callback.go
+++ b/callback.go
@@ -20,6 +20,8 @@
 
 void _sqlite3_result_text(sqlite3_context* ctx, const char* s);
 void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l);
+
+void _unlock_notify_callback(void *arg, int argc);
 */
 import "C"
 
@@ -362,3 +364,35 @@
 		return v, err
 	}
 }
+
+type unlockNotification struct {
+	notify chan struct{}
+	lock   sync.Mutex
+}
+
+//export unlock_notify_callback
+func unlock_notify_callback(pargv unsafe.Pointer, argc C.int) {
+	argv := *(*uintptr)(pargv)
+	v := (*[1 << 30]uintptr)(unsafe.Pointer(argv))
+	for i := 0; i < int(argc); i++ {
+		un := lookupHandle(v[i]).(unlockNotification)
+		un.notify <- struct{}{}
+	}
+}
+
+var notifyMutex sync.Mutex
+
+//export unlock_notify_wait
+func unlock_notify_wait(db *C.sqlite3) C.int {
+	var un unlockNotification
+
+	un.notify = make(chan struct{})
+	defer close(un.notify)
+
+	argv := [1]uintptr{newHandle(nil, un)}
+	if rv := C.sqlite3_unlock_notify(db, (*[0]byte)(C._unlock_notify_callback), unsafe.Pointer(&argv)); rv != C.SQLITE_OK {
+		return rv
+	}
+	<-un.notify
+	return C.SQLITE_OK
+}
diff --git a/sqlite3.go b/sqlite3.go
index 1ff58c3..41a05ec 100644
--- a/sqlite3.go
+++ b/sqlite3.go
@@ -11,6 +11,7 @@
 #cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4_UNICODE61
 #cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15
 #cgo CFLAGS: -DSQLITE_DISABLE_INTRINSIC
+#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
 #cgo CFLAGS: -Wno-deprecated-declarations
 #ifndef USE_LIBSQLITE3
 #include <sqlite3-binding.h>
@@ -70,8 +71,25 @@
 static int
 _sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes)
 {
-  int rv = sqlite3_step(stmt);
+  extern int unlock_notify_wait(sqlite3 *db);
+  int rv;
   sqlite3* db = sqlite3_db_handle(stmt);
+
+  for (;;) {
+    rv = sqlite3_step(stmt);
+    if (rv!=SQLITE_LOCKED) {
+      break;
+    }
+    if (sqlite3_extended_errcode(db)!=SQLITE_LOCKED_SHAREDCACHE) {
+      break;
+    }
+    rv = unlock_notify_wait(db);
+    if (rv != SQLITE_OK) {
+      break;
+    }
+    sqlite3_reset(stmt);
+  }
+
   *rowid = (long long) sqlite3_last_insert_rowid(db);
   *changes = (long long) sqlite3_changes(db);
   return rv;
@@ -814,7 +832,19 @@
 	defer C.free(unsafe.Pointer(pquery))
 	var s *C.sqlite3_stmt
 	var tail *C.char
-	rv := C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail)
+	var rv C.int
+	for {
+		rv = C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail)
+		if rv == C.SQLITE_OK {
+			break
+		}
+		if rv == C.SQLITE_LOCKED {
+			rv = unlock_notify_wait(c.db)
+			if rv != C.SQLITE_OK {
+				break
+			}
+		}
+	}
 	if rv != C.SQLITE_OK {
 		return nil, c.lastError()
 	}