On Fri, Sep 11, 2015 at 8:48 AM, Alexander Drozdov <adrozd...@gmail.com> wrote: > Hi all! > > We are found another descriptors leak :-) > > If we try to listen on TCP port and ff_listen() fails on > interrupt callback, socket (bind) descriptor overwrites at the tcp_open() > and does not closed at all. > > As a result, we can't rebind to the same port. > > Minimal sample for issue (sorry for C++ in some places :-), also sample > code assumes that librtmp does not used - it does not allow to listen): > ``` > #include <iostream> > #include <unistd.h> > > extern "C" { > #ifndef __STDC_CONSTANT_MACROS > #define __STDC_CONSTANT_MACROS > #endif > > #include <libavcodec/avcodec.h> > #include <libavformat/avformat.h> > #include <libavfilter/avfilter.h> > #include <libswscale/swscale.h> > #include <libavdevice/avdevice.h> > #include <libswresample/swresample.h> > #include <libavutil/log.h> > } > > int openInputInterruptCallBack(void *ctx) > { > // I know, stupid code :-) in real code more complex logic here > return 1; > } > > int main(int argc, char **argv) { > std::cout << "Hello, world!" << std::endl; > > avdevice_register_all(); > avcodec_register_all(); > avfilter_register_all(); > av_register_all(); > avformat_network_init(); > > AVFormatContext *mpFormatCtx = avformat_alloc_context(); > mpFormatCtx->interrupt_callback.callback = &openInputInterruptCallBack; > mpFormatCtx->interrupt_callback.opaque = mpFormatCtx; > > AVDictionary * dict = nullptr; > av_dict_set_int(&dict, "rtmp_listen", 1, 0); > av_dict_set_int(&dict, "timeout", -1, 0); > av_dict_set(&dict, "rtmp_live", "live", 0); > char* inputFileName = "rtmp://0.0.0.0:1936/live/mystream"; > AVInputFormat *pInAvFormat = av_find_input_format(inputFileName); > > int err = avformat_open_input(&mpFormatCtx, inputFileName, pInAvFormat, > &dict); > // avformat_open_input() fails here but bind socket descriptor still > open. > // we can check it via `ls -l /proc/PID/fd` > > if(err != 0) { > char errMsg[100]; > av_strerror(err, errMsg, 100); > std::cout << "Couldn't open input source: " << inputFileName <<", > err : " << errMsg << std::endl; > avformat_network_deinit(); > > for (;;) > sleep(1); > > return -1; > } else { > avformat_close_input(&mpFormatCtx); > avformat_network_deinit(); > } > > return 0; > } > ``` > > Fix is attached to the letter. > > -- > WBR, Alexander Drozdov > http://htrd.su > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >
I worked on this code and patch LGTM. I can follow where and how the filedescriptor is lost/leaked. Minor thing: the second line of the if-clause should line up with the parenthesis. Regards, Stephan _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel