Войти в систему

Home
    - Создать дневник
    - Написать в дневник
       - Подробный режим

LJ.Rossia.org
    - Новости сайта
    - Общие настройки
    - Sitemap
    - Оплата
    - ljr-fif

Редактировать...
    - Настройки
    - Список друзей
    - Дневник
    - Картинки
    - Пароль
    - Вид дневника

Сообщества

Настроить S2

Помощь
    - Забыли пароль?
    - FAQ
    - Тех. поддержка



Пишет peter_lemenkov ([info]peter_lemenkov) в [info]programming
@ 2006-10-25 17:30:00


Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Erlang и утечка памяти.
Почему это течет? Функция select_calls вызывает себя рекурсивно, но, вроде как tail recursion, так что все нормально.

select_calls(Ref,Fd,NumberOfCalls) ->
        case odbc:next(Ref) of 
                {selected,["CS_CALLER_ID","CS_CALLED_ID","CS_CALL_ID","CS_TAG_TO","CS_TAG_FROM","CS_ROUTE_TO","CS_ROUTE_FROM"], [{Caller,Called,SessionID,TagTo,TagFrom,RouteTo,RouteFrom}]} ->
                        send_msg (Fd,Caller,Called,SessionID,TagTo,TagFrom,RouteTo),
                        send_msg (Fd,Called,Caller,SessionID,TagFrom,TagTo,RouteFrom),
                        select_calls(Ref,Fd,NumberOfCalls+1);
                Error -> 
                        io:format("Select next FAILED!\n")
        end.

send_msg (Fd,Caller,Called,SessionID,TagTo,TagFrom,Route) ->
        Msg = "BYE sip:127.0.0.1:5060 SIP/2.0 \r\n"
        "Via: SIP/2.0/UDP 127.0.0.1:3456\r\n"
        "From: <" ++ Caller ++ ">;tag=" ++ TagFrom ++ "\r\n"
        "To: <" ++ Called ++ ">;tag=" ++ TagTo ++ "\r\n"
        "Call-ID: " ++ SessionID ++ "\r\n"
        "Route: <" ++ Route ++ ">\r\n"
        "CSeq: 123 BYE\r\n"
        "Content-Length: 0\r\n"
        "\r\n",

        gen_udp:send(Fd,"127.0.0.1",5060, [Msg]).


Если в функции select_calls закомментировать вызов send_msg, то ничего не течет. Так как же в erlang'е правильно строки-то отсылать через socket?


(Добавить комментарий)


[info]kouzdra
2006-10-25 22:14 (ссылка)
Я Erlang не знаю, но на вскидку select_calls возвращает тройку из результатов вызовов send_msg и select_calls. Это, естественное, не хвостовая рекурсия - потому что после вызова select_calls результат надо еще запихать в тройку. Закомментаривание вызовов send_msg, натурально, помогает.

Как из этого выходить - не знаю - зависит от языка. Если есть последовательное исполнение (кстати в Haskell и ML и даже в С++ порядок вычисления аргументов не гаратируется) - то им и воспользоваться (в ML - ; вместо , если нет - как-то по другому).

(Ответить)