diff --git a/src/fdstream.c b/src/fdstream.c index 39a875364c..32d386dce6 100644 --- a/src/fdstream.c +++ b/src/fdstream.c @@ -67,6 +67,12 @@ struct virFDStreamData { bool abortCallbackCalled; bool abortCallbackDispatching; + /* internal callback, as the regular one (from generic streams) gets + * eaten up by the server stream driver */ + virFDStreamInternalCloseCb icbCb; + virFDStreamInternalCloseCbFreeOpaque icbFreeOpaque; + void *icbOpaque; + virMutex lock; }; @@ -313,6 +319,14 @@ virFDStreamCloseInt(virStreamPtr st, bool streamAbort) st->privateData = NULL; + /* call the internal stream closing callback */ + if (fdst->icbCb) { + /* the mutex is not accessible anymore, as private data is null */ + (fdst->icbCb)(st, fdst->icbOpaque); + if (fdst->icbFreeOpaque) + (fdst->icbFreeOpaque)(fdst->icbOpaque); + } + if (fdst->dispatching) { fdst->closed = true; virMutexUnlock(&fdst->lock); @@ -687,3 +701,23 @@ int virFDStreamCreateFile(virStreamPtr st, offset, length, oflags | O_CREAT, mode); } + +int virFDStreamSetInternalCloseCb(virStreamPtr st, + virFDStreamInternalCloseCb cb, + void *opaque, + virFDStreamInternalCloseCbFreeOpaque fcb) +{ + struct virFDStreamData *fdst = st->privateData; + + virMutexLock(&fdst->lock); + + if (fdst->icbFreeOpaque) + (fdst->icbFreeOpaque)(fdst->icbOpaque); + + fdst->icbCb = cb; + fdst->icbOpaque = opaque; + fdst->icbFreeOpaque = fcb; + + virMutexUnlock(&fdst->lock); + return 0; +} diff --git a/src/fdstream.h b/src/fdstream.h index f9edb23e9e..f08cab9d63 100644 --- a/src/fdstream.h +++ b/src/fdstream.h @@ -1,7 +1,7 @@ /* * fdstream.h: generic streams impl for file descriptors * - * Copyright (C) 2009-2011 Red Hat, Inc. + * Copyright (C) 2009-2012 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +26,13 @@ # include "internal.h" # include "command.h" +/* internal callback, the generic one is used up by daemon stream driver */ +/* the close callback is called with fdstream private data locked */ +typedef void (*virFDStreamInternalCloseCb)(virStreamPtr st, void *opaque); + +typedef void (*virFDStreamInternalCloseCbFreeOpaque)(void *opaque); + + int virFDStreamOpen(virStreamPtr st, int fd); @@ -45,4 +52,8 @@ int virFDStreamCreateFile(virStreamPtr st, int oflags, mode_t mode); +int virFDStreamSetInternalCloseCb(virStreamPtr st, + virFDStreamInternalCloseCb cb, + void *opaque, + virFDStreamInternalCloseCbFreeOpaque fcb); #endif /* __VIR_FDSTREAM_H_ */