* @param arg opaque value to pass to the callback
* @returns 0 on success, negative error code on failure
*/
-int rados_watch2(rados_ioctx_t io, const char *o, uint64_t *handle,
- rados_watchcb2_t watchcb,
- rados_watchfailcb_t watchfailcb,
- rados_watcherrcb_t watcherrcb,
- void *arg);
+CEPH_RADOS_API int rados_watch2(rados_ioctx_t io, const char *o, uint64_t *handle,
+ rados_watchcb2_t watchcb,
+ rados_watchfailcb_t watchfailcb,
+ rados_watcherrcb_t watcherrcb,
+ void *arg);
/**
* Unregister an interest in an object
* watch. This should be called to clean up unneeded watchers.
*
* @param io the pool the object is in
- * @param o the name of the watched object
+ * @param o the name of the watched object (ignored)
* @param handle which watch to unregister
* @returns 0 on success, negative error code on failure
*/
-CEPH_RADOS_API int rados_unwatch(rados_ioctx_t io, const char *o,
- uint64_t handle);
+CEPH_RADOS_API int rados_unwatch(rados_ioctx_t io, const char *o, uint64_t handle)
+ __attribute__((deprecated));
+
+/**
+ * Unregister an interest in an object
+ *
+ * Once this completes, no more notifies will be sent to us for this
+ * watch. This should be called to clean up unneeded watchers.
+ *
+ * @param io the pool the object is in
+ * @param handle which watch to unregister
+ * @returns 0 on success, negative error code on failure
+ */
+CEPH_RADOS_API int rados_unwatch2(rados_ioctx_t io, uint64_t handle);
/**
* Sychronously notify watchers of an object
// watch/notify
int watch(const std::string& o, uint64_t *handle,
librados::WatchCtx2 *ctx);
- int unwatch(const std::string& o, uint64_t handle);
+ int unwatch(uint64_t handle);
int notify(const std::string& o, ///< object
bufferlist& bl, ///< optional broadcast payload
uint64_t timeout_ms, ///< timeout (in ms)
librados::WatchCtx *ctx) __attribute__ ((deprecated));
int notify(const std::string& o, uint64_t ver, bufferlist& bl)
__attribute__ ((deprecated));
+ int unwatch(const std::string& o, uint64_t handle)
+ __attribute__ ((deprecated));
/**
* Set allocation hint for an object
if (r < 0) {
lock->Lock();
- client->unregister_watch_notify_callback(*cookie); // destroys wc
+ client->unregister_watch_notify_callback(*cookie, NULL); // destroys wc
lock->Unlock();
}
return 0;
}
-int librados::IoCtxImpl::unwatch(const object_t& oid, uint64_t cookie)
+int librados::IoCtxImpl::watch_check(uint64_t cookie)
+{
+ Mutex::Locker(*lock);
+ return client->watch_check(cookie);
+}
+
+int librados::IoCtxImpl::unwatch(uint64_t cookie)
{
bufferlist inbl, outbl;
version_t ver;
lock->Lock();
- client->unregister_watch_notify_callback(cookie);
+ object_t oid;
+ r = client->unregister_watch_notify_callback(cookie, &oid);
+ if (r < 0) {
+ lock->Unlock();
+ return r;
+ }
::ObjectOperation wr;
prepare_assert_ops(&wr);
ldout(client->cct, 10) << __func__ << " completed notify (linger op " << wc->linger_id << "), unregistering" << dendl;
lock->Lock();
- client->unregister_watch_notify_callback(cookie); // destroys wc
+ client->unregister_watch_notify_callback(cookie, NULL); // destroys wc
lock->Unlock();
set_sync_op_version(objver);
void set_sync_op_version(version_t ver);
int watch(const object_t& oid, uint64_t *cookie, librados::WatchCtx *ctx,
librados::WatchCtx2 *ctx2);
- int unwatch(const object_t& oid, uint64_t cookie);
+ int unwatch(uint64_t cookie);
int notify(const object_t& oid, bufferlist& bl, uint64_t timeout_ms,
bufferlist *preplybl, char **preply_buf, size_t *preply_buf_len);
int notify_ack(const object_t& oid, uint64_t notify_id, uint64_t cookie,
watch_notify_info[wc->cookie] = wc;
}
-void librados::RadosClient::unregister_watch_notify_callback(uint64_t cookie)
+int librados::RadosClient::unregister_watch_notify_callback(uint64_t cookie,
+ object_t *poid)
{
ldout(cct,10) << __func__ << " cookie " << cookie << dendl;
assert(lock.is_locked_by_me());
- map<uint64_t, WatchNotifyInfo *>::iterator iter =
- watch_notify_info.find(cookie);
- if (iter != watch_notify_info.end()) {
- WatchNotifyInfo *ctx = iter->second;
- if (ctx->linger_id)
- objecter->unregister_linger(ctx->linger_id);
+ map<uint64_t, WatchNotifyInfo *>::iterator iter = watch_notify_info.find(cookie);
+ if (iter == watch_notify_info.end())
+ return -EBADF;
- watch_notify_info.erase(iter);
- lock.Unlock();
- ldout(cct, 10) << __func__ << " dropping reference, waiting ctx="
- << (void *)ctx << dendl;
- ctx->put_wait();
- ldout(cct, 10) << __func__ << " done ctx=" << (void *)ctx << dendl;
- lock.Lock();
- }
+ WatchNotifyInfo *ctx = iter->second;
+ if (poid)
+ *poid = ctx->oid;
+ if (ctx->linger_id)
+ objecter->unregister_linger(ctx->linger_id);
+
+ watch_notify_info.erase(iter);
+ lock.Unlock();
+ ldout(cct, 10) << __func__ << " dropping reference, waiting ctx="
+ << (void *)ctx << dendl;
+ ctx->put_wait();
+ ldout(cct, 10) << __func__ << " done ctx=" << (void *)ctx << dendl;
+ lock.Lock();
+ return 0;
+}
}
struct C_DoWatchNotify : public Context {
void register_watch_notify_callback(librados::WatchNotifyInfo *wc,
uint64_t *cookie);
- void unregister_watch_notify_callback(uint64_t cookie);
+ int unregister_watch_notify_callback(uint64_t cookie, object_t *poid);
void handle_watch_notify(MWatchNotify *m);
void do_watch_notify(MWatchNotify *m);
void do_watch_error(uint64_t cookie, int err);
int librados::IoCtx::unwatch(const string& oid, uint64_t handle)
{
- uint64_t cookie = handle;
object_t obj(oid);
- return io_ctx_impl->unwatch(obj, cookie);
+ return io_ctx_impl->unwatch(handle);
+}
+
+int librados::IoCtx::unwatch(uint64_t handle)
+{
+ return io_ctx_impl->unwatch(handle);
}
int librados::IoCtx::notify(const string& oid, uint64_t ver, bufferlist& bl)
tracepoint(librados, rados_unwatch_enter, io, o, handle);
uint64_t cookie = handle;
librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
- object_t oid(o);
- int retval = ctx->unwatch(oid, cookie);
+ int retval = ctx->unwatch(cookie);
tracepoint(librados, rados_unwatch_exit, retval);
return retval;
}
+extern "C" int rados_unwatch2(rados_ioctx_t io, uint64_t handle)
+{
+ tracepoint(librados, rados_unwatch2_enter, io, handle);
+ uint64_t cookie = handle;
+ librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
+ int retval = ctx->unwatch(cookie);
+ tracepoint(librados, rados_unwatch2_exit, retval);
+ return retval;
+}
+
extern "C" int rados_notify(rados_ioctx_t io, const char *o,
uint64_t ver, const char *buf, int buf_len)
{
ASSERT_EQ(0u, notify_cookies.size());
// re-watch
- rados_unwatch(ioctx, notify_oid, handle);
+ rados_unwatch2(ioctx, handle);
handle = 0;
ASSERT_EQ(0,
rados_watch2(ioctx, notify_oid, &handle,
}
ASSERT_EQ(1u, notify_cookies.size());
- rados_unwatch(ioctx, notify_oid, handle);
+ rados_unwatch2(ioctx, handle);
}
// --
ASSERT_EQ(1, notify_cookies.count(handle));
ASSERT_EQ(5, reply_map.begin()->second.length());
ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
- rados_unwatch(ioctx, notify_oid, handle);
+ rados_unwatch2(ioctx, handle);
}
TEST_P(LibRadosWatchNotifyPP, WatchNotify2) {
ASSERT_EQ(1u, reply_map.size());
ASSERT_EQ(5, reply_map.begin()->second.length());
ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
- ioctx.unwatch(notify_oid, handle);
+ ioctx.unwatch(handle);
}
// --
ASSERT_EQ(1, notify_cookies.count(handle1));
ASSERT_EQ(1, notify_cookies.count(handle2));
ASSERT_EQ(0, strncmp("reply", reply_map.begin()->second.c_str(), 5));
- rados_unwatch(ioctx, notify_oid, handle1);
- rados_unwatch(ioctx, notify_oid, handle2);
+ rados_unwatch2(ioctx, handle1);
+ rados_unwatch2(ioctx, handle2);
}
// --
&reply_buf, &reply_buf_len));
ASSERT_EQ(1u, notify_cookies.size());
- rados_unwatch(ioctx, notify_oid, handle);
+ rados_unwatch2(ioctx, handle);
}
TEST_P(LibRadosWatchNotifyPP, WatchNotify2Timeout) {
while (!notify_failed && --wait)
sleep(1);
ASSERT_TRUE(notify_failed);
- ioctx.unwatch(notify_oid, handle);
+ ioctx.unwatch(handle);
}
// --
)
)
+TRACEPOINT_EVENT(librados, rados_unwatch2_enter,
+ TP_ARGS(
+ rados_ioctx_t, ioctx,
+ uint64_t, handle),
+ TP_FIELDS(
+ ctf_integer_hex(rados_ioctx_t, ioctx, ioctx)
+ ctf_integer(uint64_t, handle, handle)
+ )
+)
+
+TRACEPOINT_EVENT(librados, rados_unwatch2_exit,
+ TP_ARGS(
+ int, retval),
+ TP_FIELDS(
+ ctf_integer(int, retval, retval)
+ )
+)
+
TRACEPOINT_EVENT(librados, rados_notify_enter,
TP_ARGS(
rados_ioctx_t, ioctx,