Changeset 600e2cd549142370607f55455aa29de0d6d1cd8e
- Timestamp:
- 22/02/07 00:15:06
(2 years ago)
- Author:
- Laurent Aimar <fenrir@videolan.org>
- git-committer:
- Laurent Aimar <fenrir@videolan.org> 1172099706 +0000
- git-parent:
[9886e26b218171b39bf57b0efa72e3ff2cad7e77]
- git-author:
- Laurent Aimar <fenrir@videolan.org> 1172099706 +0000
- Message:
Changed input_DestroyThread to take care of detaching, cleaning and destroying input.
(This way it matches input_CreateThread and fixes a memleak)
Control variables are now created even for preparse, only callback are not added.
(This fix use of uninitialized variables)
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r85ff146 |
r600e2cd |
|
| 201 | 201 | input_StopThread( p_sd->p_sys->pp_input[i] ); |
|---|
| 202 | 202 | input_DestroyThread( p_sd->p_sys->pp_input[i] ); |
|---|
| 203 | | vlc_object_detach( p_sd->p_sys->pp_input[i] ); |
|---|
| 204 | | vlc_object_destroy( p_sd->p_sys->pp_input[i] ); |
|---|
| 205 | 203 | p_sd->p_sys->pp_input[i] = NULL; |
|---|
| 206 | 204 | } |
|---|
| … | … | |
| 234 | 232 | input_StopThread( p_sd->p_sys->pp_input[i] ); |
|---|
| 235 | 233 | input_DestroyThread( p_sd->p_sys->pp_input[i] ); |
|---|
| 236 | | vlc_object_detach( p_sd->p_sys->pp_input[i] ); |
|---|
| 237 | | vlc_object_destroy( p_sd->p_sys->pp_input[i] ); |
|---|
| 238 | 234 | p_sd->p_sys->pp_input[i] = NULL; |
|---|
| 239 | 235 | } |
|---|
| rd1093a8 |
r600e2cd |
|
| 50 | 50 | *****************************************************************************/ |
|---|
| 51 | 51 | static int Run ( input_thread_t *p_input ); |
|---|
| 52 | | static int RunAndClean ( input_thread_t *p_input ); |
|---|
| | 52 | static int RunAndDestroy ( input_thread_t *p_input ); |
|---|
| 53 | 53 | |
|---|
| 54 | 54 | static input_thread_t * Create ( vlc_object_t *, input_item_t *, |
|---|
| … | … | |
| 198 | 198 | |
|---|
| 199 | 199 | /* Create Objects variables for public Get and Set */ |
|---|
| 200 | | if( !p_input->b_preparsing ) |
|---|
| 201 | | input_ControlVarInit( p_input ); |
|---|
| | 200 | input_ControlVarInit( p_input ); |
|---|
| 202 | 201 | |
|---|
| 203 | 202 | p_input->p->input.i_cr_average = var_GetInteger( p_input, "cr-average" ); |
|---|
| … | … | |
| 255 | 254 | VLC_META_NOW_PLAYING ); /* ? Don't translate as it might has been copied ? */ |
|---|
| 256 | 255 | |
|---|
| | 256 | /* */ |
|---|
| | 257 | if( p_input->b_preparsing ) |
|---|
| | 258 | p_input->i_flags |= OBJECT_FLAGS_QUIET | OBJECT_FLAGS_NOINTERACT; |
|---|
| | 259 | |
|---|
| | 260 | /* Attach only once we are ready */ |
|---|
| | 261 | vlc_object_attach( p_input, p_parent ); |
|---|
| | 262 | |
|---|
| 257 | 263 | return p_input; |
|---|
| 258 | 264 | } |
|---|
| 259 | 265 | |
|---|
| | 266 | static void Destroy( input_thread_t *p_input ) |
|---|
| | 267 | { |
|---|
| | 268 | vlc_object_detach( p_input ); |
|---|
| | 269 | |
|---|
| | 270 | vlc_mutex_destroy( &p_input->p->lock_control ); |
|---|
| | 271 | free( p_input->p ); |
|---|
| | 272 | |
|---|
| | 273 | vlc_object_destroy( p_input ); |
|---|
| | 274 | } |
|---|
| 260 | 275 | /** |
|---|
| 261 | 276 | * Initialize an input thread and run it. You will need to monitor the |
|---|
| … | … | |
| 283 | 298 | return NULL; |
|---|
| 284 | 299 | |
|---|
| 285 | | /* Now we can attach our new input */ |
|---|
| 286 | | vlc_object_attach( p_input, p_parent ); |
|---|
| 287 | | |
|---|
| 288 | 300 | /* Create thread and wait for its readiness. */ |
|---|
| 289 | 301 | if( vlc_thread_create( p_input, "input", Run, |
|---|
| … | … | |
| 292 | 304 | input_ChangeState( p_input, ERROR_S ); |
|---|
| 293 | 305 | msg_Err( p_input, "cannot create input thread" ); |
|---|
| 294 | | vlc_object_detach( p_input ); |
|---|
| 295 | | free( p_input->p ); |
|---|
| 296 | | vlc_object_destroy( p_input ); |
|---|
| | 306 | Destroy( p_input ); |
|---|
| 297 | 307 | return NULL; |
|---|
| 298 | 308 | } |
|---|
| … | … | |
| 319 | 329 | return VLC_EGENERIC; |
|---|
| 320 | 330 | |
|---|
| 321 | | /* Now we can attach our new input */ |
|---|
| 322 | | vlc_object_attach( p_input, p_parent ); |
|---|
| 323 | | |
|---|
| 324 | 331 | if( b_block ) |
|---|
| 325 | 332 | { |
|---|
| 326 | | RunAndClean( p_input ); |
|---|
| | 333 | RunAndDestroy( p_input ); |
|---|
| 327 | 334 | return VLC_SUCCESS; |
|---|
| 328 | 335 | } |
|---|
| 329 | 336 | else |
|---|
| 330 | 337 | { |
|---|
| 331 | | if( vlc_thread_create( p_input, "input", RunAndClean, |
|---|
| | 338 | if( vlc_thread_create( p_input, "input", RunAndDestroy, |
|---|
| 332 | 339 | VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) ) |
|---|
| 333 | 340 | { |
|---|
| 334 | 341 | input_ChangeState( p_input, ERROR_S ); |
|---|
| 335 | 342 | msg_Err( p_input, "cannot create input thread" ); |
|---|
| 336 | | vlc_object_detach( p_input ); |
|---|
| 337 | | free( p_input->p ); |
|---|
| 338 | | vlc_object_destroy( p_input ); |
|---|
| | 343 | Destroy( p_input ); |
|---|
| 339 | 344 | return VLC_EGENERIC; |
|---|
| 340 | 345 | } |
|---|
| … | … | |
| 360 | 365 | return VLC_EGENERIC; |
|---|
| 361 | 366 | |
|---|
| 362 | | p_input->i_flags |= OBJECT_FLAGS_QUIET; |
|---|
| 363 | | p_input->i_flags |= OBJECT_FLAGS_NOINTERACT; |
|---|
| 364 | | |
|---|
| 365 | | /* Now we can attach our new input */ |
|---|
| 366 | | vlc_object_attach( p_input, p_parent ); |
|---|
| 367 | | |
|---|
| 368 | 367 | Init( p_input ); |
|---|
| 369 | 368 | |
|---|
| … | … | |
| 371 | 370 | InputSourceClean( p_input, &p_input->p->input ); |
|---|
| 372 | 371 | |
|---|
| | 372 | /* FIXME shouldn't we call End() to ? */ |
|---|
| | 373 | |
|---|
| 373 | 374 | /* Unload all modules */ |
|---|
| 374 | 375 | if( p_input->p->p_es_out ) input_EsOutDelete( p_input->p->p_es_out ); |
|---|
| 375 | 376 | |
|---|
| 376 | | vlc_object_detach( p_input ); |
|---|
| 377 | | free( p_input->p ); |
|---|
| 378 | | vlc_object_destroy( p_input ); |
|---|
| | 377 | Destroy( p_input ); |
|---|
| 379 | 378 | |
|---|
| 380 | 379 | return VLC_SUCCESS; |
|---|
| … | … | |
| 435 | 434 | vlc_thread_join( p_input ); |
|---|
| 436 | 435 | |
|---|
| 437 | | /* Delete input lock (only after thread joined) */ |
|---|
| 438 | | vlc_mutex_destroy( &p_input->p->lock_control ); |
|---|
| 439 | | |
|---|
| 440 | | /* TODO: maybe input_DestroyThread should also delete p_input instead |
|---|
| 441 | | * of the playlist but I'm not sure if it's possible */ |
|---|
| | 436 | /* */ |
|---|
| | 437 | Destroy( p_input ); |
|---|
| 442 | 438 | } |
|---|
| 443 | 439 | |
|---|
| … | … | |
| 499 | 495 | |
|---|
| 500 | 496 | /***************************************************************************** |
|---|
| 501 | | * RunAndClean: main thread loop |
|---|
| | 497 | * RunAndDestroy: main thread loop |
|---|
| 502 | 498 | * This is the "just forget me" thread that spawns the input processing chain, |
|---|
| 503 | 499 | * reads the stream, cleans up and releases memory |
|---|
| 504 | 500 | *****************************************************************************/ |
|---|
| 505 | | static int RunAndClean( input_thread_t *p_input ) |
|---|
| | 501 | static int RunAndDestroy( input_thread_t *p_input ) |
|---|
| 506 | 502 | { |
|---|
| 507 | 503 | /* Signal that the thread is launched */ |
|---|
| … | … | |
| 509 | 505 | |
|---|
| 510 | 506 | if( Init( p_input ) ) |
|---|
| 511 | | { |
|---|
| 512 | | /* If we failed, just exit */ |
|---|
| 513 | | return 0; |
|---|
| 514 | | } |
|---|
| | 507 | goto exit; |
|---|
| 515 | 508 | |
|---|
| 516 | 509 | MainLoop( p_input ); |
|---|
| … | … | |
| 536 | 529 | End( p_input ); |
|---|
| 537 | 530 | |
|---|
| | 531 | exit: |
|---|
| 538 | 532 | /* Release memory */ |
|---|
| 539 | | vlc_object_detach( p_input ); |
|---|
| 540 | | free( p_input->p ); |
|---|
| 541 | | vlc_object_destroy( p_input ); |
|---|
| 542 | | |
|---|
| | 533 | Destroy( p_input ); |
|---|
| 543 | 534 | return 0; |
|---|
| 544 | 535 | } |
|---|
| … | … | |
| 1144 | 1135 | int i; |
|---|
| 1145 | 1136 | |
|---|
| 1146 | | msg_Dbg( p_input, "closing input" ); |
|---|
| 1147 | | |
|---|
| 1148 | 1137 | /* We are at the end */ |
|---|
| 1149 | 1138 | input_ChangeState( p_input, END_S ); |
|---|
| 1150 | 1139 | |
|---|
| 1151 | 1140 | /* Clean control variables */ |
|---|
| 1152 | | if( !p_input->b_preparsing ) |
|---|
| 1153 | | input_ControlVarClean( p_input ); |
|---|
| | 1141 | input_ControlVarClean( p_input ); |
|---|
| 1154 | 1142 | |
|---|
| 1155 | 1143 | /* Clean up master */ |
|---|
| r496a542 |
r600e2cd |
|
| 76 | 76 | vlc_value_t val, text; |
|---|
| 77 | 77 | |
|---|
| | 78 | /* XXX we put callback only in non preparsing mode. We need to create the variable |
|---|
| | 79 | * unless someone want to check all var_Get/var_Change return value ... */ |
|---|
| | 80 | #define ADD_CALLBACK( name, callback ) do { if( !p_input->b_preparsing ) { var_AddCallback( p_input, name, callback, NULL ); } } while(0) |
|---|
| 78 | 81 | /* State */ |
|---|
| 79 | 82 | var_Create( p_input, "state", VLC_VAR_INTEGER ); |
|---|
| 80 | 83 | val.i_int = p_input->i_state; |
|---|
| 81 | 84 | var_Change( p_input, "state", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 82 | | var_AddCallback( p_input, "state", StateCallback, NULL ); |
|---|
| | 85 | ADD_CALLBACK( "state", StateCallback ); |
|---|
| 83 | 86 | |
|---|
| 84 | 87 | /* Rate */ |
|---|
| … | … | |
| 86 | 89 | val.i_int = p_input->p->i_rate; |
|---|
| 87 | 90 | var_Change( p_input, "rate", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 88 | | var_AddCallback( p_input, "rate", RateCallback, NULL ); |
|---|
| | 91 | ADD_CALLBACK( "rate", RateCallback ); |
|---|
| 89 | 92 | |
|---|
| 90 | 93 | var_Create( p_input, "rate-slower", VLC_VAR_VOID ); |
|---|
| 91 | | var_AddCallback( p_input, "rate-slower", RateCallback, NULL ); |
|---|
| | 94 | ADD_CALLBACK( "rate-slower", RateCallback ); |
|---|
| 92 | 95 | |
|---|
| 93 | 96 | var_Create( p_input, "rate-faster", VLC_VAR_VOID ); |
|---|
| 94 | | var_AddCallback( p_input, "rate-faster", RateCallback, NULL ); |
|---|
| | 97 | ADD_CALLBACK( "rate-faster", RateCallback ); |
|---|
| 95 | 98 | |
|---|
| 96 | 99 | /* Position */ |
|---|
| … | … | |
| 99 | 102 | val.f_float = 0.0; |
|---|
| 100 | 103 | var_Change( p_input, "position", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 101 | | var_AddCallback( p_input, "position", PositionCallback, NULL ); |
|---|
| 102 | | var_AddCallback( p_input, "position-offset", PositionCallback, NULL ); |
|---|
| | 104 | ADD_CALLBACK( "position", PositionCallback ); |
|---|
| | 105 | ADD_CALLBACK( "position-offset", PositionCallback ); |
|---|
| 103 | 106 | |
|---|
| 104 | 107 | /* Time */ |
|---|
| … | … | |
| 107 | 110 | val.i_time = 0; |
|---|
| 108 | 111 | var_Change( p_input, "time", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 109 | | var_AddCallback( p_input, "time", TimeCallback, NULL ); |
|---|
| 110 | | var_AddCallback( p_input, "time-offset", TimeCallback, NULL ); |
|---|
| | 112 | ADD_CALLBACK( "time", TimeCallback ); |
|---|
| | 113 | ADD_CALLBACK( "time-offset", TimeCallback ); |
|---|
| 111 | 114 | |
|---|
| 112 | 115 | /* Bookmark */ |
|---|
| … | … | |
| 115 | 118 | val.psz_string = _("Bookmark"); |
|---|
| 116 | 119 | var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, &val, NULL ); |
|---|
| 117 | | var_AddCallback( p_input, "bookmark", BookmarkCallback, NULL ); |
|---|
| | 120 | ADD_CALLBACK( "bookmark", BookmarkCallback ); |
|---|
| 118 | 121 | |
|---|
| 119 | 122 | /* Program */ |
|---|
| … | … | |
| 125 | 128 | text.psz_string = _("Program"); |
|---|
| 126 | 129 | var_Change( p_input, "program", VLC_VAR_SETTEXT, &text, NULL ); |
|---|
| 127 | | var_AddCallback( p_input, "program", ProgramCallback, NULL ); |
|---|
| | 130 | ADD_CALLBACK( "program", ProgramCallback ); |
|---|
| 128 | 131 | |
|---|
| 129 | 132 | /* Programs */ |
|---|
| … | … | |
| 136 | 139 | text.psz_string = _("Title"); |
|---|
| 137 | 140 | var_Change( p_input, "title", VLC_VAR_SETTEXT, &text, NULL ); |
|---|
| 138 | | var_AddCallback( p_input, "title", TitleCallback, NULL ); |
|---|
| | 141 | ADD_CALLBACK( "title", TitleCallback ); |
|---|
| 139 | 142 | |
|---|
| 140 | 143 | /* Chapter */ |
|---|
| … | … | |
| 142 | 145 | text.psz_string = _("Chapter"); |
|---|
| 143 | 146 | var_Change( p_input, "chapter", VLC_VAR_SETTEXT, &text, NULL ); |
|---|
| 144 | | var_AddCallback( p_input, "chapter", SeekpointCallback, NULL ); |
|---|
| | 147 | ADD_CALLBACK( "chapter", SeekpointCallback ); |
|---|
| 145 | 148 | |
|---|
| 146 | 149 | /* Navigation The callback is added after */ |
|---|
| … | … | |
| 153 | 156 | val.i_time = 0; |
|---|
| 154 | 157 | var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 155 | | var_AddCallback( p_input, "audio-delay", EsDelayCallback, NULL ); |
|---|
| | 158 | ADD_CALLBACK( "audio-delay", EsDelayCallback ); |
|---|
| 156 | 159 | var_Create( p_input, "spu-delay", VLC_VAR_TIME ); |
|---|
| 157 | 160 | val.i_time = 0; |
|---|
| 158 | 161 | var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 159 | | var_AddCallback( p_input, "spu-delay", EsDelayCallback, NULL ); |
|---|
| | 162 | ADD_CALLBACK( "spu-delay", EsDelayCallback ); |
|---|
| 160 | 163 | |
|---|
| 161 | 164 | /* Video ES */ |
|---|
| … | … | |
| 163 | 166 | text.psz_string = _("Video Track"); |
|---|
| 164 | 167 | var_Change( p_input, "video-es", VLC_VAR_SETTEXT, &text, NULL ); |
|---|
| 165 | | var_AddCallback( p_input, "video-es", ESCallback, NULL ); |
|---|
| | 168 | ADD_CALLBACK( "video-es", ESCallback ); |
|---|
| 166 | 169 | |
|---|
| 167 | 170 | /* Audio ES */ |
|---|
| … | … | |
| 169 | 172 | text.psz_string = _("Audio Track"); |
|---|
| 170 | 173 | var_Change( p_input, "audio-es", VLC_VAR_SETTEXT, &text, NULL ); |
|---|
| 171 | | var_AddCallback( p_input, "audio-es", ESCallback, NULL ); |
|---|
| | 174 | ADD_CALLBACK( "audio-es", ESCallback ); |
|---|
| 172 | 175 | |
|---|
| 173 | 176 | /* Spu ES */ |
|---|
| … | … | |
| 175 | 178 | text.psz_string = _("Subtitles Track"); |
|---|
| 176 | 179 | var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, &text, NULL ); |
|---|
| 177 | | var_AddCallback( p_input, "spu-es", ESCallback, NULL ); |
|---|
| | 180 | ADD_CALLBACK( "spu-es", ESCallback ); |
|---|
| 178 | 181 | |
|---|
| 179 | 182 | /* Special read only objects variables for intf */ |
|---|
| … | … | |
| 184 | 187 | var_Change( p_input, "length", VLC_VAR_SETVALUE, &val, NULL ); |
|---|
| 185 | 188 | |
|---|
| 186 | | /* Special "intf-change" variable, it allows intf to set up a callback |
|---|
| 187 | | * to be notified of some changes. |
|---|
| 188 | | * TODO list all changes warn by this callbacks */ |
|---|
| 189 | | var_Create( p_input, "intf-change", VLC_VAR_BOOL ); |
|---|
| 190 | | var_SetBool( p_input, "intf-change", VLC_TRUE ); |
|---|
| 191 | | |
|---|
| 192 | | /* item-change variable */ |
|---|
| 193 | | var_Create( p_input, "item-change", VLC_VAR_INTEGER ); |
|---|
| | 189 | if( !p_input->b_preparsing ) |
|---|
| | 190 | { |
|---|
| | 191 | /* Special "intf-change" variable, it allows intf to set up a callback |
|---|
| | 192 | * to be notified of some changes. |
|---|
| | 193 | * TODO list all changes warn by this callbacks */ |
|---|
| | 194 | var_Create( p_input, "intf-change", VLC_VAR_BOOL ); |
|---|
| | 195 | var_SetBool( p_input, "intf-change", VLC_TRUE ); |
|---|
| | 196 | |
|---|
| | 197 | /* item-change variable */ |
|---|
| | 198 | var_Create( p_input, "item-change", VLC_VAR_INTEGER ); |
|---|
| | 199 | } |
|---|
| | 200 | #undef ADD_CALLBACK |
|---|
| 194 | 201 | } |
|---|
| 195 | 202 | |
|---|
| r9886e26 |
r600e2cd |
|
| 1148 | 1148 | input_StopThread( p_input ); |
|---|
| 1149 | 1149 | input_DestroyThread( p_input ); |
|---|
| 1150 | | vlc_object_detach( p_input ); |
|---|
| 1151 | | vlc_object_destroy( p_input ); |
|---|
| 1152 | 1150 | } |
|---|
| 1153 | 1151 | free( psz_output ); |
|---|
| … | … | |
| 1242 | 1240 | input_StopThread( p_instance->p_input ); |
|---|
| 1243 | 1241 | input_DestroyThread( p_instance->p_input ); |
|---|
| 1244 | | vlc_object_detach( p_instance->p_input ); |
|---|
| 1245 | | vlc_object_destroy( p_instance->p_input ); |
|---|
| 1246 | 1242 | } |
|---|
| 1247 | 1243 | |
|---|
| … | … | |
| 1363 | 1359 | input_StopThread( p_instance->p_input ); |
|---|
| 1364 | 1360 | input_DestroyThread( p_instance->p_input ); |
|---|
| 1365 | | vlc_object_detach( p_instance->p_input ); |
|---|
| 1366 | | vlc_object_destroy( p_instance->p_input ); |
|---|
| 1367 | 1361 | } |
|---|
| 1368 | 1362 | |
|---|
| … | … | |
| 2498 | 2492 | input_StopThread( p_instance->p_input ); |
|---|
| 2499 | 2493 | input_DestroyThread( p_instance->p_input ); |
|---|
| 2500 | | vlc_object_detach( p_instance->p_input ); |
|---|
| 2501 | | vlc_object_destroy( p_instance->p_input ); |
|---|
| 2502 | 2494 | |
|---|
| 2503 | 2495 | p_instance->i_index++; |
|---|
| rcb4a2b8 |
r600e2cd |
|
| 260 | 260 | input_DestroyThread( p_input ); |
|---|
| 261 | 261 | |
|---|
| 262 | | /* Unlink current input |
|---|
| 263 | | * (_after_ input_DestroyThread for vout garbage collector) */ |
|---|
| 264 | | vlc_object_detach( p_input ); |
|---|
| 265 | | |
|---|
| 266 | | /* Destroy object */ |
|---|
| 267 | | vlc_object_destroy( p_input ); |
|---|
| 268 | | |
|---|
| 269 | 262 | PL_LOCK; |
|---|
| 270 | 263 | |
|---|
| … | … | |
| 390 | 383 | /* Destroy input */ |
|---|
| 391 | 384 | input_DestroyThread( p_input ); |
|---|
| 392 | | /* Unlink current input (_after_ input_DestroyThread for vout |
|---|
| 393 | | * garbage collector)*/ |
|---|
| 394 | | vlc_object_detach( p_input ); |
|---|
| 395 | | |
|---|
| 396 | | /* Destroy object */ |
|---|
| 397 | | vlc_object_destroy( p_input ); |
|---|
| 398 | 385 | continue; |
|---|
| 399 | 386 | } |
|---|