@@ -8,11 +8,10 @@ defmodule Membrane.Core.Bin.PadController do
88 alias Membrane . { Core , LinkError , Pad }
99 alias Membrane.Core.Bin . { ActionHandler , CallbackContext , State }
1010 alias Membrane.Core . { CallbackHandler , Child , Message }
11- alias Membrane.Core.Child.PadModel
1211 alias Membrane.Core.Element.StreamFormatController
1312 alias Membrane.Core.Parent . { ChildLifeController , Link , SpecificationParser }
1413
15- require Membrane.Core.Child.PadModel
14+ require Membrane.Core.Child.PadModel , as: PadModel
1615 require Membrane.Core.Message
1716 require Membrane.Logger
1817 require Membrane.Pad
@@ -50,8 +49,7 @@ defmodule Membrane.Core.Bin.PadController do
5049 state =
5150 case PadModel . get_data ( state , pad_ref ) do
5251 { :error , :unknown_pad } ->
53- init_pad_data ( pad_ref , pad_info , state )
54- |> Map . update! ( :pad_refs , & [ pad_ref | & 1 ] )
52+ init_pad_data ( pad_ref , state )
5553
5654 # This case is for pads that were instantiated before the external link request,
5755 # that is in the internal link request (see `handle_internal_link_request/4`).
@@ -69,17 +67,19 @@ defmodule Membrane.Core.Bin.PadController do
6967 state
7068 end
7169
72- state = PadModel . update_data! ( state , pad_ref , & % { & 1 | link_id: link_id , options: pad_options } )
73- state = maybe_handle_pad_added ( pad_ref , state )
70+ linking_timeout_id = make_ref ( )
7471
75- unless PadModel . get_data! ( state , pad_ref , :endpoint ) do
76- # If there's no endpoint associated to the pad, no internal link to the pad
77- # has been requested in the bin yet
78- _ref = Process . send_after ( self ( ) , Message . new ( :linking_timeout , pad_ref ) , 5000 )
79- :ok
80- end
72+ state =
73+ PadModel . update_data! (
74+ state ,
75+ pad_ref ,
76+ & % { & 1 | link_id: link_id , linking_timeout_id: linking_timeout_id , options: pad_options }
77+ )
8178
82- state
79+ message = Message . new ( :linking_timeout , [ pad_ref , linking_timeout_id ] )
80+ _ref = Process . send_after ( self ( ) , message , 5000 )
81+
82+ maybe_handle_pad_added ( pad_ref , state )
8383 end
8484
8585 @ spec remove_pad ( Pad . ref ( ) , State . t ( ) ) :: State . t ( )
@@ -102,16 +102,16 @@ defmodule Membrane.Core.Bin.PadController do
102102 end
103103 end
104104
105- @ spec handle_linking_timeout ( Pad . ref ( ) , State . t ( ) ) :: :ok | no_return ( )
106- def handle_linking_timeout ( pad_ref , state ) do
107- case PadModel . get_data ( state , pad_ref ) do
108- { :ok , % { endpoint: nil } = pad_data } ->
109- raise Membrane.LinkError ,
110- "Bin pad #{ inspect ( pad_ref ) } wasn't linked internally within timeout. Pad data: #{ inspect ( pad_data , pretty: true ) } "
111-
112- _other ->
113- :ok
105+ @ spec handle_linking_timeout ( Pad . ref ( ) , reference ( ) , State . t ( ) ) :: :ok | no_return ( )
106+ def handle_linking_timeout ( pad_ref , linking_timeout_id , state ) do
107+ with { :ok , pad_data } <- PadModel . get_data ( state , pad_ref ) ,
108+ % { linking_timeout_id: ^ linking_timeout_id , linked_in_spec?: false } <- pad_data do
109+ raise Membrane.LinkError , """
110+ Bin pad #{ inspect ( pad_ref ) } wasn't linked internally within timeout. Pad data: #{ PadModel . get_data ( state , pad_ref ) |> inspect ( pretty: true ) }
111+ """
114112 end
113+
114+ :ok
115115 end
116116
117117 @ doc """
@@ -139,7 +139,7 @@ defmodule Membrane.Core.Bin.PadController do
139139
140140 # Static pads can be linked internally before the external link request
141141 pad_info . availability == :always ->
142- init_pad_data ( pad_ref , pad_info , state )
142+ init_pad_data ( pad_ref , state )
143143
144144 true ->
145145 raise LinkError , "Dynamic pads must be firstly linked externally, then internally"
@@ -284,7 +284,6 @@ defmodule Membrane.Core.Bin.PadController do
284284 with { :ok , % { availability: :on_request } } <- PadModel . get_data ( state , pad_ref ) do
285285 { pad_data , state } =
286286 maybe_handle_pad_removed ( pad_ref , state )
287- |> Map . update! ( :pad_refs , & List . delete ( & 1 , pad_ref ) )
288287 |> PadModel . pop_data! ( pad_ref )
289288
290289 if pad_data . endpoint do
@@ -316,8 +315,8 @@ defmodule Membrane.Core.Bin.PadController do
316315 end
317316
318317 @ spec maybe_handle_pad_added ( Pad . ref ( ) , Core.Bin.State . t ( ) ) :: Core.Bin.State . t ( )
319- defp maybe_handle_pad_added ( ref , state ) do
320- % { options: pad_opts , availability: availability } = PadModel . get_data! ( state , ref )
318+ defp maybe_handle_pad_added ( pad_ref , state ) do
319+ % { options: pad_opts , availability: availability } = PadModel . get_data! ( state , pad_ref )
321320
322321 if Pad . availability_mode ( availability ) == :dynamic do
323322 context = & CallbackContext . from_state ( & 1 , pad_options: pad_opts )
@@ -326,7 +325,7 @@ defmodule Membrane.Core.Bin.PadController do
326325 :handle_pad_added ,
327326 ActionHandler ,
328327 % { context: context } ,
329- [ ref ] ,
328+ [ pad_ref ] ,
330329 state
331330 )
332331 else
@@ -351,9 +350,15 @@ defmodule Membrane.Core.Bin.PadController do
351350 end
352351 end
353352
354- defp init_pad_data ( pad_ref , pad_info , state ) do
353+ @ spec init_pad_data ( Pad . ref ( ) , State . t ( ) ) :: State . t ( )
354+ def init_pad_data ( pad_ref , state ) do
355+ if PadModel . assert_instance ( state , pad_ref ) == :ok do
356+ raise "Cannot init pad data for pad #{ inspect ( pad_ref ) } , because it already exists"
357+ end
358+
355359 pad_data =
356- pad_info
360+ state . pads_info
361+ |> Map . get ( Pad . name_by_ref ( pad_ref ) )
357362 |> Map . delete ( :accepted_formats_str )
358363 |> Map . merge ( % {
359364 ref: pad_ref ,
@@ -362,10 +367,12 @@ defmodule Membrane.Core.Bin.PadController do
362367 linked?: false ,
363368 response_received?: false ,
364369 spec_ref: nil ,
365- options: nil
370+ options: nil ,
371+ linking_timeout_id: nil ,
372+ linked_in_spec?: false
366373 } )
367374 |> then ( & struct! ( Membrane.Bin.PadData , & 1 ) )
368375
369- put_in ( state , [ : pads_data, pad_ref ] , pad_data )
376+ put_in ( state . pads_data [ pad_ref ] , pad_data )
370377 end
371378end
0 commit comments