RT-Thread论坛
登录
直播中
李郝荫
8年用户
1414经验值
私信
关注
[问答]
alloc_socket在不断创建socket时会不断新建信号量和互斥锁,导致内存泄漏,怎么解决?
开启该帖子的消息推送
Socket
alloc
alloc_socket在不断创建socket时会不断新建信号量和互斥锁,导致内存泄漏。
修改前:
sta
ti
c struct wiz_socket *alloc_socket(void)
{
static rt_mutex_t wiz_slock = RT_NULL;
struct wiz_socket *sock = RT_NULL;
char name[RT_NAME_MAX] = {0};
int idx = 0;
if (wiz_slock == RT_NULL)
{
/* create WIZnet socket lock */
wiz_slock = rt_mutex_create("w_lock", RT_IPC_FLAG_FIFO);
if (wiz_slock == RT_NULL)
{
LOG_E("No memory for WIZnet socket lock!");
return RT_NULL;
}
}
rt_mutex_take(wiz_slock, RT_WAITING_FOREVER);
/* find an empty WIZnet socket entry */
for (idx = 0; idx < WIZ_SOCKETS_NUM && sockets[idx].magic; idx++);
/* can't find an empty protocol family entry */
if (idx == WIZ_SOCKETS_NUM)
{
goto __err;
}
sock = &(sockets[idx]);
sock->magic = WIZ_SOCKET_MAGIC;
sock->socket = idx;
sock->port = 0;
sock->state = SOCK_CLOSED;
sock->remote_addr = RT_NULL;
sock->recv_timeout = 0;
sock->send_timeout = 0;
sock->rcvevent = 0;
sock->sendevent = 0;
sock->errevent = 0;
/* for server socket */
sock->svr_info = RT_NULL;
rt_snprintf(name, RT_NAME_MAX, "%s%d", "wiz_sr", idx);
/* create WIZnet socket receive mailbox */
if ((sock->recv_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO)) == RT_NULL)
{
goto __err;
}
rt_snprintf(name, RT_NAME_MAX, "%s%d", "wiz_sr", idx);
/* create WIZnet socket receive ring buffer lock */
if ((sock->recv_lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO)) == RT_NULL)
{
goto __err;
}
rt_mutex_release(wiz_slock);
return sock;
__err:
rt_mutex_release(wiz_slock);
return RT_NULL;
}
修改后:
static struct wiz_socket *alloc_socket(void)
{
static rt_mutex_t wiz_slock = RT_NULL;
struct wiz_socket *sock = RT_NULL;
char name[RT_NAME_MAX] = {0};
int idx = 0;
if (wiz_slock == RT_NULL)
{
/* create WIZnet socket lock */
wiz_slock = rt_mutex_create("w_lock", RT_IPC_FLAG_FIFO);
if (wiz_slock == RT_NULL)
{
LOG_E("No memory for WIZnet socket lock!");
return RT_NULL;
}
}
rt_mutex_take(wiz_slock, RT_WAITING_FOREVER);
/* find an empty WIZnet socket entry */
for (idx = 0; idx < WIZ_SOCKETS_NUM && sockets[idx].magic; idx++);
/* can't find an empty protocol family entry */
if (idx == WIZ_SOCKETS_NUM)
{
goto __err;
}
sock = &(sockets[idx]);
sock->magic = WIZ_SOCKET_MAGIC;
sock->socket = idx;
sock->port = 0;
sock->state = SOCK_CLOSED;
sock->remote_addr = RT_NULL;
sock->recv_timeout = 0;
sock->send_timeout = 0;
sock->rcvevent = 0;
sock->sendevent = 0;
sock->errevent = 0;
/* for server socket */
sock->svr_info = RT_NULL;
rt_snprintf(name, RT_NAME_MAX, "%s%d", "wiz_sr", idx);
/* create WIZnet socket receive mailbox */
if (sock->recv_notice == RT_NULL) {
if ((sock->recv_notice = rt_sem_create(name, 0, RT_IPC_FLAG_FIFO)) == RT_NULL)
{
goto __err;
}
}
rt_snprintf(name, RT_NAME_MAX, "%s%d", "wiz_sr", idx);
/* create WIZnet socket receive ring buffer lock */
if (sock->recv_lock == RT_NULL) {
if ((sock->recv_lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO)) == RT_NULL)
{
goto __err;
}
}
rt_mutex_release(wiz_slock);
return sock;
__err:
// 释放资源
rt_sem_delete(sock->recv_notice);
rt_mutex_delete(sock->recv_lock);
sock->recv_notice = RT_NULL;
sock->recv_lock = RT_NULL;
rt_mutex_release(wiz_slock);
return RT_NULL;
}
还得添加修改:
return -1前需要释放socket
int wiz_socket(int domain, int type, int protocol)
{
struct wiz_socket *sock = RT_NULL;
uint8_t socket_type = 0;
uint8_t socket_state = 0;
/* check WIZnet initialize status */
WIZ_INIT_STATUS_CHECK;
/* check socket family protocol */
RT_ASSERT(domain == 46 || domain == 2);
switch (type)
{
case SOCK_STREAM:
socket_type = Sn_MR_TCP;
break;
case SOCK_DGRAM:
socket_type = Sn_MR_UDP;
break;
case SOCK_RAW:
socket_type = Sn_MR_IPRAW;
break;
default:
LOG_E("don't support socket type (%d)!", type);
return -1;
}
/* allocate and initialize a new WIZnet socket */
sock = alloc_socket();
if (sock == RT_NULL)
{
LOG_E("allocate a new WIZnet socket failed!");
return -1;
}
sock->type = socket_type;
#ifdef SAL_USING_POSIX
rt_wqueue_init(&sock->wait_head);
#endif
socket_state = getSn_SR(sock->socket);
if (socket_state == SOCK_CLOSED)
{
switch (sock->type)
{
case Sn_MR_TCP:
if (wizchip_socket(sock->socket, sock->type, wiz_port, Sn_MR_ND) != sock->socket)
{
LOG_E("WIZnet TCP socket(%d) create failed!", sock->socket);
free_socket(sock);
rt_memset(sock, 0x00, sizeof(struct wiz_socket));
return -1;
}
sock->port = wiz_port++;
break;
case Sn_MR_UDP:
case Sn_MR_IPRAW:
if (wizchip_socket(sock->socket, sock->type, wiz_port, 0) != sock->socket)
{
LOG_E("WIZnet UDP socket(%d) create failed!", sock->socket);
free_socket(sock);
rt_memset(sock, 0x00, sizeof(struct wiz_socket));
return -1;
}
sock->port = wiz_port++;
break;
default:
LOG_E("Socket (%d) type %d is not support.", sock->socket, sock->type);
free_socket(sock);
rt_memset(sock, 0x00, sizeof(struct wiz_socket));
return -1;
}
}
else
{
free_socket(sock);
rt_memset(sock, 0x00, sizeof(struct wiz_socket));
LOG_E("socket(%d) is not closed(0x%x).", sock->socket, socket_state);
return -1;
}
sock->state = SOCK_INIT;
return sock->socket;
}
回帖
(1)
刘丰标
2025-9-10 17:38:30
sock释放时,对应的recv_notice和recv_lock没有释放吗?
感觉在那里释放更合理些,不然只要申请过,后面即使不用了,也会一直占用资源。
sock释放时,对应的recv_notice和recv_lock没有释放吗?
感觉在那里释放更合理些,不然只要申请过,后面即使不用了,也会一直占用资源。
举报
更多回帖
rotate(-90deg);
回复
相关问答
Socket
alloc
信号量
和
互斥
信号量
该怎么选择?
2019-08-26
3086
FreeRTOS
互斥
信号量
是怎样去控制LED亮灭的
2022-02-28
1074
AT组件中的at_skt0 等等的
信号量
是什么情况下产生的?怎么产生的?
2023-05-11
1534
例程使用
互斥
信号量
初始化如何设置?
2020-06-02
1907
关于UCOSIII的
信号量
和
互斥
信号量
的理解?
2020-03-13
2040
w5500通信使用wiz包时,拔掉网线后如何释放网络资源?
2023-09-03
2195
使用w5500通信使用wiz包的时候,突然拔掉网线,如何释放网络资源?
2025-10-11
476
信号量
和
互斥
量
在
使用过程中会存在这样的死锁吗?
2023-01-10
714
信号量
和
互斥
信号量
理解
2020-04-21
1756
Rt-thread里面的mem.c函数保护lfree全局变量为什么用
信号量
2022-08-08
1981
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分