merge: leaks, nested seq segv, ffmpeg avi frames
authorGood Guy <good1.2guy@gmail.com>
Wed, 30 Mar 2016 22:01:40 +0000 (16:01 -0600)
committerGood Guy <good1.2guy@gmail.com>
Wed, 30 Mar 2016 22:01:40 +0000 (16:01 -0600)
20 files changed:
cinelerra-5.1/bld_scripts/bld_package.sh
cinelerra-5.1/cinelerra/asset.C
cinelerra-5.1/cinelerra/asset.inc
cinelerra-5.1/cinelerra/assetedit.C
cinelerra-5.1/cinelerra/audiodevice.C
cinelerra-5.1/cinelerra/automation.C
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/ffmpeg.h
cinelerra-5.1/cinelerra/formattools.C
cinelerra-5.1/cinelerra/formattools.h
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/pluginclient.C
cinelerra-5.1/cinelerra/tracking.C
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/guicast/bcsignals.C
cinelerra-5.1/guicast/bcsynchronous.C
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/guicast/condition.h
cinelerra-5.1/guicast/thread.C

index ff715bf49e582c2687e07e4b47e02ee58f912222..9a88437a0ed72ea4698aac0004eb31b18a1eebdd 100755 (executable)
@@ -14,7 +14,12 @@ proj="cinelerra5"
 base="cinelerra-5.1"
 
 centos="centos-7.0-1406"
+fedora="fedora-23"
+leap="leap-42.1"
+mint="mint-14.04.1"
 suse="opensuse-13.2"
+ub14="ubuntu-14.04.1"
+ub15="ubuntu-15.10"
 ubuntu="ubuntu-14.04.1"
 
 eval os="\${$dir}"
index 598068eb8e5052714e6f109cd82f6191ed41cdd0..5350004cd4dbfe5285602b5db1d479b349e88561 100644 (file)
@@ -1014,17 +1014,17 @@ int Asset::dump(FILE *fp)
        fprintf(fp,"   ff_video_bitrate=%d\n", ff_video_bitrate);
        fprintf(fp,"   ff_video_quality=%d\n", ff_video_quality);
        fprintf(fp,"   audio_data %d channels %d samplerate %d bits %d"
-               " byte_order %d signed %d header %d dither %d acodec %c%c%c%c\n",
+               " byte_order %d signed %d header %d dither %d acodec %4.4s\n",
                audio_data, channels, sample_rate, bits, byte_order, signed_,
-               header, dither, acodec[0], acodec[1], acodec[2], acodec[3]);
+               header, dither, acodec);
        fprintf(fp,"   audio_length %jd\n", audio_length);
        char string[BCTEXTLEN];
        ilacemode_to_xmltext(string, interlace_mode);
        fprintf(fp,"   video_data %d program %d layers %d framerate %f width %d"
-               " height %d vcodec %c%c%c%c aspect_ratio %f ilace_mode %s\n",
+               " height %d vcodec %4.4s aspect_ratio %f ilace_mode %s\n",
                video_data, layers, program, frame_rate, width, height,
-               vcodec[0], vcodec[1], vcodec[2], vcodec[3], aspect_ratio,string);
-       printf("   reel_name %s reel_number %i tcstart %jd tcend %jd tcf %d\n",
+               vcodec, aspect_ratio,string);
+       fprintf(fp,"   reel_name %s reel_number %i tcstart %jd tcend %jd tcf %d\n",
                reel_name, reel_number, tcstart, tcend, tcformat);
        fprintf(fp,"   video_length %jd \n", video_length);
 
index 291709df4bae56cea0e933870e05d004a7ff6f82..2b73d0b02342e8ef3a2dfc940be8978a29e3bd21 100644 (file)
 #ifndef ASSET_INC
 #define ASSET_INC
 
-
 class Asset;
-class InterlaceautofixoptionItem;
 class InterlacefixmethodItem;
 
-
-
 #endif
index cb633437472323ed4709f55dbe992df32ab0bc8e..92e70a2ae611128a5e81e70738cc1026e9775deb 100644 (file)
@@ -517,7 +517,7 @@ void AssetEditWindow::create_objects()
 
                add_subwindow(new BC_Title(x, y, _("Frame rate:")));
                x = x2;
-               sprintf(string, "%.2f", asset_edit->changed_params->frame_rate);
+               sprintf(string, "%.4f", asset_edit->changed_params->frame_rate);
 
 //printf("AssetEditWindow::create_objects %d %f\n", __LINE__, asset_edit->changed_params->frame_rate);
                if(asset)
index 82a9b8cf4705e99a3dbe79225b7fb0e53a7007b7..a6aebcb406a3be000427390f03cae279bdaadb90 100644 (file)
@@ -151,6 +151,7 @@ AudioThread(AudioDevice *device,
 
 AudioThread::~AudioThread()
 {
+       stop(0);
        delete startup_lock;
 }
 
index 298618af3359bedfe9ec9163d5fc91d4ee599f6b..1ce714fbbf715f38985c6ca58624b48df15464a7 100644 (file)
@@ -100,9 +100,6 @@ void Automation::create_objects()
        autos[AUTOMATION_MUTE]->create_objects();
        autos[AUTOMATION_MUTE]->autoidx = AUTOMATION_MUTE;
        autos[AUTOMATION_MUTE]->autogrouptype = AUTOGROUPTYPE_INT255;
-       autos[AUTOMATION_SPEED] = new FloatAutos(edl, track, 1.0);
-       autos[AUTOMATION_SPEED]->create_objects();
-       autos[AUTOMATION_SPEED]->autogrouptype = AUTOGROUPTYPE_SPEED;
 }
 
 Automation& Automation::operator=(Automation& automation)
index e494932799e62ef35f7da82fe3488ad033ac8061..68a131589b9306794143ddba06753bd77bc2e32b 100644 (file)
@@ -362,6 +362,7 @@ int FFStream::decode(AVFrame *frame)
                if( ipkt->stream_index == st->index ) {
                        while( (ipkt->size > 0 || !ipkt->data) && !got_frame ) {
                                ret = decode_frame(ipkt, frame, got_frame);
+                               if( ret < 0 ) need_packet = 1;
                                if( ret <= 0 || !ipkt->data ) break;
                                ipkt->data += ret;
                                ipkt->size -= ret;
@@ -732,6 +733,9 @@ int FFVideoStream::decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame)
                ff_err(ret, "FFVideoStream::decode_frame: Could not read video frame\n");
                return -1;
        }
+       else // this is right out of ffplay, looks questionable ???
+               ret = pkt->size;
+
        if( got_frame ) {
                int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame);
                if( pkt_ts != AV_NOPTS_VALUE )
@@ -1191,6 +1195,38 @@ int FFMPEG::scan_option_line(char *cp, char *tag, char *val)
        return 0;
 }
 
+int FFMPEG::load_defaults(const char *path, const char *type,
+                char *codec, char *codec_options, int len)
+{
+       char default_file[BCTEXTLEN];
+       FFMPEG::set_option_path(default_file, "%s/%s.dfl", path, type);
+       FILE *fp = fopen(default_file,"r");
+       if( !fp ) return 1;
+       fgets(codec, BCSTRLEN, fp);
+       char *cp = codec;
+       while( *cp && *cp!='\n' ) ++cp;
+       *cp = 0;
+       while( len > 0 && fgets(codec_options, len, fp) ) {
+               int n = strlen(codec_options);
+               codec_options += n;  len -= n;
+       }
+       fclose(fp);
+       FFMPEG::set_option_path(default_file, "%s/%s", path, codec);
+       return FFMPEG::load_options(default_file, codec_options, len);
+}
+
+void FFMPEG::set_asset_format(Asset *asset, const char *text)
+{
+       if( asset->format != FILE_FFMPEG ) return;
+       strcpy(asset->fformat, text);
+       strcpy(asset->ff_audio_options, "");
+       strcpy(asset->ff_video_options, "");
+       asset->audio_data = !load_defaults("audio", text, asset->acodec,
+               asset->ff_audio_options, sizeof(asset->ff_audio_options));
+       asset->video_data = !load_defaults("video", text, asset->vcodec,
+               asset->ff_video_options, sizeof(asset->ff_video_options));
+}
+
 int FFMPEG::get_encoder(const char *options,
                char *format, char *codec, char *bsfilter, char *bsargs)
 {
index d9ca7836bbe0a2eb1776a3fbc4dda042805b2c3b..4860c0021dd1c9a9d868d5a435e4e1e9b263620f 100644 (file)
@@ -263,6 +263,9 @@ public:
        static void get_option_path(char *path, const char *type, const char *spec);
        static int get_format(char *format, const char *path, char *spec);
        static int scan_option_line(char *cp,char *tag,char *val);
+       static int load_defaults(const char *path, const char *type,
+                char *codec, char *codec_options, int len);
+       static void set_asset_format(Asset *asset, const char *text);
        int get_file_format();
        int get_encoder(const char *options,
                char *format, char *codec, char *bsfilter, char *bsargs);
index a86fbfa293503879a49232f0c621e498af338150..37810a8ee748275695d04799c7ba152429f58337 100644 (file)
@@ -213,10 +213,10 @@ void FormatTools::create_objects(int &init_x,
        format_button->create_objects();
        x += format_button->get_w() + 5;
        window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 50, 1, asset->fformat));
+       FFMPEG::set_asset_format(asset, asset->fformat);
        x += ffmpeg_type->get_w();
        window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this));
        format_ffmpeg->create_objects();
-
        x = init_x;
        y += format_button->get_h() + 10;
        if(do_audio)
@@ -845,40 +845,13 @@ FormatFFMPEG::~FormatFFMPEG()
 {
 }
 
-int FormatFFMPEG::load_defaults(const char *path, const char *type,
-                char *codec, char *codec_options, int len)
-{
-       char default_file[BCTEXTLEN];
-       FFMPEG::set_option_path(default_file, "%s/%s.dfl", path, type);
-       FILE *fp = fopen(default_file,"r");
-       if( !fp ) return 1;
-       fgets(codec, BCSTRLEN, fp);
-       char *cp = codec;
-       while( *cp && *cp!='\n' ) ++cp;
-       *cp = 0;
-       while( len > 0 && fgets(codec_options, len, fp) ) {
-               int n = strlen(codec_options);
-               codec_options += n;  len -= n;
-       }
-       fclose(fp);
-       FFMPEG::set_option_path(default_file, "%s/%s", path, codec);
-       return FFMPEG::load_options(default_file, codec_options, len);
-}
-
 int FormatFFMPEG::handle_event()
 {
        BC_ListBoxItem *selection = get_selection(0, 0);
        if( selection ) {
                char *text = get_selection(0, 0)->get_text();
                format->ffmpeg_type->update(text);
-               Asset *asset = format->asset;
-               strcpy(asset->fformat, text);
-               strcpy(asset->ff_audio_options, "");
-               strcpy(asset->ff_video_options, "");
-               asset->audio_data = !load_defaults("audio", text, asset->acodec,
-                       asset->ff_audio_options, sizeof(asset->ff_audio_options));
-               asset->video_data = !load_defaults("video", text, asset->vcodec,
-                       asset->ff_video_options, sizeof(asset->ff_video_options));
+               FFMPEG::set_asset_format(format->asset, text);
                format->update_extension();
                format->close_format_windows();
                format->update_format();
index b5b567684eebf1125de1b781b61ca780dc917f44..3929bbff5ec02f0058f5c6e001e8d6a73dcfacb3 100644 (file)
@@ -167,8 +167,6 @@ public:
 
        int handle_event();
        FormatTools *format;
-       static int load_defaults(const char *path, const char *type,
-               char *codec, char *codec_options, int len);
 
 // squash show/hide window
        int show_window(int flush=1) { return 0; }
index 18b9a239bb6e7fb127a0eb2f0f44981018d412a2..adb7a87aaa868e746eb879ab5bda531c2fa6a459 100644 (file)
@@ -214,6 +214,8 @@ MWindow::MWindow()
 MWindow::~MWindow()
 {
        in_destructor = 1;
+       stop_playback(1);
+       stop_brender();
 //printf("MWindow::~MWindow %d\n", __LINE__);
        gui->stop_drawing();
        gui->remote_control->deactivate();
@@ -230,9 +232,9 @@ MWindow::~MWindow()
 
 // Save defaults for open plugins
        plugin_gui_lock->lock("MWindow::~MWindow");
-       for(int i = 0; i < plugin_guis->size(); i++)
-       {
+       for(int i = 0; i < plugin_guis->size(); i++) {
                plugin_guis->get(i)->hide_gui();
+               delete_plugin(plugin_guis->get(i));
        }
        plugin_gui_lock->unlock();
        hide_keyframe_guis();
@@ -277,10 +279,10 @@ MWindow::~MWindow()
        join();
 #endif
        reset_caches();
-       dead_plugins->remove_all();
+       dead_plugins->remove_all_objects();
+       delete_plugins();
        finit_error();
        keyframe_threads->remove_all_objects();
-       if( !edl->Garbage::remove_user() ) edl = 0;
        colormodels.remove_all_objects();
        delete gui;             gui = 0;
        delete render;          render = 0;
@@ -303,12 +305,13 @@ MWindow::~MWindow()
        delete keyframe_threads;  keyframe_threads = 0;
        delete undo;            undo = 0;
        delete preferences;     preferences = 0;
+       delete exportedl;       exportedl = 0;
        delete session;         session = 0;
        delete defaults;        defaults = 0;
        delete assets;          assets = 0;
        delete splash_window;   splash_window = 0;
-       delete theme;           theme = 0;
-       delete_plugins();
+//     delete theme;           theme = 0;      // deleted by delete_plugins
+       if( !edl->Garbage::remove_user() ) edl = 0;
        delete channeldb_buz;
        delete channeldb_v4l2jpeg;
 // This must be last thread to exit
@@ -318,6 +321,10 @@ MWindow::~MWindow()
        delete vwindows_lock;
        delete brender_lock;
        delete keyframe_gui_lock;
+       colormodels.remove_all_objects();
+       interlace_project_modes.remove_all_objects();
+       interlace_asset_modes.remove_all_objects();
+       interlace_asset_fixmethods.remove_all_objects();
        sighandler->terminate();
        delete sighandler;
 }
@@ -2361,12 +2368,8 @@ void MWindow::show_plugin(Plugin *plugin)
 
 SET_TRACE
 // Remove previously deleted plugin GUIs
-       dead_plugin_lock->lock("MWindow::delete_plugin");
-       for(int i = 0; i < dead_plugins->size(); i++)
-       {
-               delete dead_plugins->get(i);
-       }
-       dead_plugins->remove_all();
+       dead_plugin_lock->lock("MWindow::show_plugin");
+       dead_plugins->remove_all_objects();
        dead_plugin_lock->unlock();
 
 //printf("MWindow::show_plugin %d\n", __LINE__);
@@ -2399,7 +2402,8 @@ SET_TRACE
 //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui);
                if(server && server->uses_gui)
                {
-                       PluginServer *gui = plugin_guis->append(new PluginServer(*server));
+                       PluginServer *gui = new PluginServer(*server);
+                       plugin_guis->append(gui);
 // Needs mwindow to do GUI
                        gui->set_mwindow(this);
                        gui->open_plugin(0, preferences, edl, plugin);
index 0ac72d2ad329f74cff5fcad45bae678e69dd957d..00e9dea829621b75af16b5e631253e4b9f5249ae 100644 (file)
@@ -526,7 +526,6 @@ public:
 
 // Menu items
        ArrayList<ColormodelItem*> colormodels;
-       ArrayList<InterlaceautofixoptionItem*> interlace_asset_autofixoptions;
        ArrayList<InterlacemodeItem*>          interlace_project_modes;
        ArrayList<InterlacemodeItem*>          interlace_asset_modes;
        ArrayList<InterlacefixmethodItem*>     interlace_asset_fixmethods;
index 64c7d53f6649d64ef1e0131d59e688d764c15fc5..c401ef22dd19634f00196342d573505251256491 100644 (file)
@@ -56,9 +56,8 @@ PluginClientThread::PluginClientThread(PluginClient *client)
 PluginClientThread::~PluginClientThread()
 {
 //printf("PluginClientThread::~PluginClientThread %p %d\n", this, __LINE__);
-       delete window;
+       join();
 //printf("PluginClientThread::~PluginClientThread %p %d\n", this, __LINE__);
-       window = 0;
        delete init_complete;
 }
 
@@ -85,8 +84,7 @@ void PluginClientThread::run()
 //printf("PluginClientThread::run %p %d\n", this, __LINE__);
                window->hide_window(1);
                window->unlock_window();
-
-
+               delete window;  window = 0;
 // Can't save defaults in the destructor because it's not called immediately
 // after closing.
                /* if(client->defaults) */ client->save_defaults_xml();
@@ -144,35 +142,14 @@ PluginClientWindow::PluginClientWindow(PluginClient *client,
  : BC_Window(client->gui_string, 
        client->window_x /* - w / 2 */, 
        client->window_y /* - h / 2 */, 
-       w, 
-       h, 
-       min_w, 
-       min_h,
-       allow_resize, 
-       0,
-       1)
+       w, h, min_w, min_h, allow_resize, 0, 1)
 {
        this->client = client;
 }
 
 PluginClientWindow::PluginClientWindow(const char *title, 
-       int x,
-       int y,
-       int w,
-       int h,
-       int min_w,
-       int min_h,
-       int allow_resize)
- : BC_Window(title, 
-       x, 
-       y, 
-       w, 
-       h, 
-       min_w, 
-       min_h,
-       allow_resize, 
-       0,
-       1)
+       int x, int y, int w, int h, int min_w, int min_h, int allow_resize)
+ : BC_Window(title, x, y, w, h, min_w, min_h, allow_resize, 0, 1)
 {
        this->client = 0;
 }
@@ -217,11 +194,7 @@ PluginClient::PluginClient(PluginServer *server)
 PluginClient::~PluginClient()
 {
 // Delete the GUI thread.  The GUI must be hidden with hide_gui first.
-       if(thread) 
-       {
-               thread->join();
-               delete thread;
-       }
+       delete thread;
 
 // Virtual functions don't work here.
        if(defaults) delete defaults;
@@ -384,7 +357,7 @@ int PluginClient::set_string()
        if(thread)
        {
                thread->window->lock_window("PluginClient::set_string");
-               thread->window->set_title(gui_string);
+               thread->window->put_title(gui_string);
                thread->window->unlock_window();
        }
        return 0;
index 5a4ef42e2e1094147466f66390a8a3675dc46cb5..1ca59993e9aa5a31ae383de3916b15200c041389 100644 (file)
@@ -106,7 +106,6 @@ int Tracking::stop_playback()
                update_tracker(position);
        
                stop_meters();
-               state = DONE;
        }
        return 0;
 }
index fd9d557e44c9f1566368e1c89a57cd0796b794f3..48f2643dafb6ecb42c1e1c488ebc12b04730d5bf 100644 (file)
@@ -452,7 +452,8 @@ int VModule::import_frame(VFrame *output,
 //                     current_edit->asset->interlace_fixmethod);
 
                        // Determine the interlacing method to use.
-                       int interlace_fixmethod = ilaceautofixmethod2(get_edl()->session->interlace_mode,
+                       int interlace_fixmethod = !current_edit->asset ? BC_ILACE_FIXMETHOD_NONE :
+                                ilaceautofixmethod2(get_edl()->session->interlace_mode,
                                        current_edit->asset->interlace_autofixoption,
                                        current_edit->asset->interlace_mode,
                                        current_edit->asset->interlace_fixmethod);
index e2a8b149c42659c1744496f814e19c08797ef2aa..609ea1e2afbbbd0c5633948c9dcc77f0241d2dc0 100644 (file)
@@ -22,6 +22,7 @@
 #include "bcsignals.h"
 #include "bcwindowbase.h"
 #include "bckeyboard.h"
+#include "bcresources.h"
 
 #include <ctype.h>
 #include <dirent.h>
@@ -126,14 +127,14 @@ static bc_buffertrace_t* new_bc_buffertrace(int size, void *ptr, const char *loc
        return result;
 }
 
-static void bc_copy_textfile(FILE *ofp, const char *fmt,...)
+static void bc_copy_textfile(int lines, FILE *ofp, const char *fmt,...)
 {
        va_list ap;    va_start(ap, fmt);
        char bfr[BCTEXTLEN];  vsnprintf(bfr, sizeof(bfr), fmt, ap);
        va_end(ap);
        FILE *ifp = fopen(bfr,"r");
        if( !ifp ) return;
-       while( fgets(bfr,sizeof(bfr),ifp) ) fputs(bfr,ofp);
+       while( --lines >= 0 && fgets(bfr,sizeof(bfr),ifp) ) fputs(bfr,ofp);
        fclose(ifp);
 }
 
@@ -855,6 +856,8 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
                fprintf(fp,"        by %d:%d %s(%s)\n",
                        pw->pw_uid, pw->pw_gid, pw->pw_name, pw->pw_gecos);
        }
+       fprintf(fp,"\nCPUS: %d\n",   BC_Resources::get_machine_cpus());
+       fprintf(fp,"\nCPUINFO:\n");  bc_copy_textfile(32, fp,"/proc/cpuinfo");
        fprintf(fp,"\nTHREADS:\n");  Thread::dump_threads(fp);
        fprintf(fp,"\nTRACES:\n");   BC_Signals::dump_traces(fp);
        fprintf(fp,"\nLOCKS:\n");    BC_Signals::dump_locks(fp);
@@ -863,9 +866,9 @@ static void handle_dump(int n, siginfo_t * info, void *sc)
                fprintf(fp,"\nMAIN HOOK:\n");
                BC_Signals::trap_hook(fp, BC_Signals::trap_data);
        }
-       fprintf(fp,"\nVERSION:\n");  bc_copy_textfile(fp,"/proc/version");
-       fprintf(fp,"\nMEMINFO:\n");  bc_copy_textfile(fp,"/proc/meminfo");
-       fprintf(fp,"\nMAPS:\n");     bc_copy_textfile(fp,"/proc/%d/maps",pid);
+       fprintf(fp,"\nVERSION:\n");  bc_copy_textfile(INT_MAX, fp,"/proc/version");
+       fprintf(fp,"\nMEMINFO:\n");  bc_copy_textfile(INT_MAX, fp,"/proc/meminfo");
+       fprintf(fp,"\nMAPS:\n");     bc_copy_textfile(INT_MAX, fp,"/proc/%d/maps",pid);
        fprintf(fp,"\n\n");
        if( fp != stdout ) fclose(fp);
        char cmd[1024], *cp = cmd;
index 4459fa363051686b076228c832d08b51f4f67776..a8eccf2356298c07765b52a5419f39a2f7ad8302 100644 (file)
@@ -460,6 +460,7 @@ void BC_Synchronous::delete_display_sync(BC_SynchronousCommand *command)
        Display *display = command->display;
        XLockDisplay(display);
        XUnlockDisplay(display);
+       glXMakeContextCurrent(display, None, None, 0);
        XCloseDisplay(display);
 #endif
 }
index c61691f2ffc9bf80c60c143cc3b6e5206a0c9a88..389670c338e4dbff8843842cc7a5255589fb8a93 100644 (file)
@@ -186,7 +186,6 @@ BC_WindowBase::~BC_WindowBase()
                }
 #endif
                finit_im();
-
                flush();
                sync_display();
 
index 8ab4fd870c62e3de0b53a564b46440a29cda8a4a..1fd455e2e1400d42c452670e1ed2df1b45a13333 100644 (file)
@@ -30,7 +30,6 @@ public:
        Condition(int init_value = 0, const char *title = 0, int is_binary = 0);
        ~Condition();
 
-
 // Reset to init_value whether locked or not.
        void reset();
 // Block if value <= 0, then decrease value
@@ -43,9 +42,9 @@ public:
        int timed_lock(int microseconds, const char *location = 0);
        int get_value();
 
-    pthread_cond_t cond;
-    pthread_mutex_t mutex;
-    int value;
+       pthread_cond_t cond;
+       pthread_mutex_t mutex;
+       int value;
        int init_value;
        int is_binary;
        const char *title;
index c3d068e0b3c867bfadd06572433bfa27b63c2d49..3d817272221f3049dba6e633d3ba72f9c256dab4 100644 (file)
@@ -46,8 +46,8 @@ Mutex MLocker::the_lock;
 
 class the_dbg {
 public:
-       pthread_t tid;  const char *name;
-       the_dbg(pthread_t t, const char *nm) { tid = t; name = nm; }
+       pthread_t tid, owner;  const char *name;
+       the_dbg(pthread_t t, pthread_t o, const char *nm) { tid = t; owner = o; name = nm; }
        ~the_dbg() {}
 };
 
@@ -62,7 +62,7 @@ public:
        }
 } thread_list;
 
-static void dbg_add(pthread_t tid, const char *nm)
+static void dbg_add(pthread_t tid, pthread_t owner, const char *nm)
 {
        MLocker mlkr;
        int i = thread_list.size();
@@ -72,7 +72,7 @@ static void dbg_add(pthread_t tid, const char *nm)
                        (unsigned long)tid, nm, thread_list[i]->name);
                return;
        }
-       thread_list.append(new the_dbg(tid, nm));
+       thread_list.append(new the_dbg(tid, owner, nm));
 }
 
 static void dbg_del(pthread_t tid)
@@ -93,9 +93,10 @@ public:
        ~the_chkr() {
                int i = thread_list.size();
                if( !i ) return;
-               printf("unjoined tids %d\n", i);
-               while( --i >= 0 ) printf("  %016lx %s\n",
+               printf("unjoined tids / owner %d\n", i);
+               while( --i >= 0 ) printf("  %016lx / %016lx %s\n",
                        (unsigned long)thread_list[i]->tid,
+                       (unsigned long)thread_list[i]->owner,
                        thread_list[i]->name);
        }
 } the_chk;
@@ -182,7 +183,7 @@ void Thread::start()
 
        pthread_create(&tid, &attr, Thread::entrypoint, this);
 
-       dbg_add(tid, typeid(*this).name());
+       dbg_add(tid, owner, typeid(*this).name());
 }
 
 int Thread::cancel()
@@ -315,8 +316,8 @@ void Thread::dump_threads(FILE *fp)
 {
        int i = thread_list.size();
        while( --i >= 0 ) {
-               fprintf(fp, "thread %016lx, %s\n",
-                       (unsigned long)thread_list[i]->tid,
+               fprintf(fp, "thread %016lx, owner %016lx, %s\n",
+                       (unsigned long)thread_list[i]->tid, (unsigned long)thread_list[i]->owner,
                        thread_list[i]->name);
        }
 }